diff --git a/thys/Functional_Ordered_Resolution_Prover/IsaFoR_Term.thy b/thys/Functional_Ordered_Resolution_Prover/IsaFoR_Term.thy --- a/thys/Functional_Ordered_Resolution_Prover/IsaFoR_Term.thy +++ b/thys/Functional_Ordered_Resolution_Prover/IsaFoR_Term.thy @@ -1,781 +1,781 @@ (* Title: Integration of IsaFoR Terms and the Knuth-Bendix Order Author: Dmitriy Traytel , 2014 Author: Anders Schlichtkrull , 2017 Maintainer: Anders Schlichtkrull *) section \Integration of \textsf{IsaFoR} Terms and the Knuth--Bendix Order\ text \ This theory implements the abstract interface for atoms and substitutions using the \textsf{IsaFoR} library. \ theory IsaFoR_Term imports Deriving.Derive Ordered_Resolution_Prover.Abstract_Substitution First_Order_Terms.Unification First_Order_Terms.Subsumption "HOL-Cardinals.Wellorder_Extension" Open_Induction.Restricted_Predicates Knuth_Bendix_Order.KBO begin hide_const (open) mgu abbreviation subst_apply_literal :: "('f, 'v) term literal \ ('f, 'v, 'w) gsubst \ ('f, 'w) term literal" (infixl "\lit" 60) where "L \lit \ \ map_literal (\A. A \ \) L" definition subst_apply_clause :: "('f, 'v) term clause \ ('f, 'v, 'w) gsubst \ ('f, 'w) term clause" (infixl "\cls" 60) where "C \cls \ = image_mset (\L. L \lit \) C" abbreviation vars_lit :: "('f, 'v) term literal \ 'v set" where "vars_lit L \ vars_term (atm_of L)" definition vars_clause :: "('f, 'v) term clause \ 'v set" where "vars_clause C = Union (set_mset (image_mset vars_lit C))" definition vars_clause_list :: "('f, 'v) term clause list \ 'v set" where "vars_clause_list Cs = Union (vars_clause ` set Cs) " definition vars_partitioned :: "('f,'v) term clause list \ bool" where "vars_partitioned Cs \ (\i < length Cs. \j < length Cs. i \ j \ (vars_clause (Cs ! i) \ vars_clause (Cs ! j)) = {})" lemma vars_clause_mono: "S \# C \ vars_clause S \ vars_clause C" unfolding vars_clause_def by auto interpretation substitution_ops "(\)" Var "(\\<^sub>s)" . lemma is_ground_atm_is_ground_on_var: assumes "is_ground_atm (A \ \)" and "v \ vars_term A" shows "is_ground_atm (\ v)" using assms proof (induction A) case (Var x) then show ?case by auto next case (Fun f ts) then show ?case unfolding is_ground_atm_def by auto qed lemma is_ground_lit_is_ground_on_var: assumes ground_lit: "is_ground_lit (subst_lit L \)" and v_in_L: "v \ vars_lit L" shows "is_ground_atm (\ v)" proof - let ?A = "atm_of L" from v_in_L have A_p: "v \ vars_term ?A" by auto then have "is_ground_atm (?A \ \)" using ground_lit unfolding is_ground_lit_def by auto then show ?thesis using A_p is_ground_atm_is_ground_on_var by metis qed lemma is_ground_cls_is_ground_on_var: assumes ground_clause: "is_ground_cls (subst_cls C \)" and v_in_C: "v \ vars_clause C" shows "is_ground_atm (\ v)" proof - from v_in_C obtain L where L_p: "L \# C" "v \ vars_lit L" unfolding vars_clause_def by auto then have "is_ground_lit (subst_lit L \)" using ground_clause unfolding is_ground_cls_def subst_cls_def by auto then show ?thesis using L_p is_ground_lit_is_ground_on_var by metis qed lemma is_ground_cls_list_is_ground_on_var: assumes ground_list: "is_ground_cls_list (subst_cls_list Cs \)" and v_in_Cs: "v \ vars_clause_list Cs" shows "is_ground_atm (\ v)" proof - from v_in_Cs obtain C where C_p: "C \ set Cs" "v \ vars_clause C" unfolding vars_clause_list_def by auto then have "is_ground_cls (subst_cls C \)" using ground_list unfolding is_ground_cls_list_def subst_cls_list_def by auto then show ?thesis using C_p is_ground_cls_is_ground_on_var by metis qed lemma same_on_vars_lit: assumes "\v \ vars_lit L. \ v = \ v" shows "subst_lit L \ = subst_lit L \" using assms proof (induction L) case (Pos x) then have "\v \ vars_term x. \ v = \ v \ subst_atm_abbrev x \ = subst_atm_abbrev x \" using term_subst_eq by metis+ then show ?case unfolding subst_lit_def using Pos by auto next case (Neg x) then have "\v \ vars_term x. \ v = \ v \ subst_atm_abbrev x \ = subst_atm_abbrev x \" using term_subst_eq by metis+ then show ?case unfolding subst_lit_def using Neg by auto qed lemma in_list_of_mset_in_S: assumes "i < length (list_of_mset S)" shows "list_of_mset S ! i \# S" proof - from assms have "list_of_mset S ! i \ set (list_of_mset S)" by auto then have "list_of_mset S ! i \# mset (list_of_mset S)" by (meson in_multiset_in_set) then show ?thesis by auto qed lemma same_on_vars_clause: assumes "\v \ vars_clause S. \ v = \ v" shows "subst_cls S \ = subst_cls S \" by (smt assms image_eqI image_mset_cong2 mem_simps(9) same_on_vars_lit set_image_mset subst_cls_def vars_clause_def) lemma vars_partitioned_var_disjoint: assumes "vars_partitioned Cs" shows "var_disjoint Cs" unfolding var_disjoint_def proof (intro allI impI) fix \s :: \('b \ ('a, 'b) term) list\ assume "length \s = length Cs" with assms[unfolded vars_partitioned_def] Fun_More.fun_merge[of "map vars_clause Cs" "nth \s"] obtain \ where \_p: "\i < length (map vars_clause Cs). \x \ map vars_clause Cs ! i. \ x = (\s ! i) x" by auto have "\i < length Cs. \S. S \# Cs ! i \ subst_cls S (\s ! i) = subst_cls S \" proof (rule, rule, rule, rule) fix i :: nat and S :: "('a, 'b) term literal multiset" assume "i < length Cs" and "S \# Cs ! i" then have "\v \ vars_clause S. (\s ! i) v = \ v" using vars_clause_mono[of S "Cs ! i"] \_p by auto then show "subst_cls S (\s ! i) = subst_cls S \" using same_on_vars_clause by auto qed then show "\\. \iS. S \# Cs ! i \ subst_cls S (\s ! i) = subst_cls S \" by auto qed lemma vars_in_instance_in_range_term: "vars_term (subst_atm_abbrev A \) \ Union (image vars_term (range \))" by (induction A) auto lemma vars_in_instance_in_range_lit: "vars_lit (subst_lit L \) \ Union (image vars_term (range \))" proof (induction L) case (Pos A) have "vars_term (A \ \) \ Union (image vars_term (range \))" using vars_in_instance_in_range_term[of A \] by blast then show ?case by auto next case (Neg A) have "vars_term (A \ \) \ Union (image vars_term (range \))" using vars_in_instance_in_range_term[of A \] by blast then show ?case by auto qed lemma vars_in_instance_in_range_cls: "vars_clause (subst_cls C \) \ Union (image vars_term (range \))" unfolding vars_clause_def subst_cls_def using vars_in_instance_in_range_lit[of _ \] by auto primrec renamings_apart :: "('f, nat) term clause list \ (('f, nat) subst) list" where "renamings_apart [] = []" | "renamings_apart (C # Cs) = (let \s = renamings_apart Cs in (\v. Var (v + Max (vars_clause_list (subst_cls_lists Cs \s) \ {0}) + 1)) # \s)" definition var_map_of_subst :: "('f, nat) subst \ nat \ nat" where "var_map_of_subst \ v = the_Var (\ v)" lemma len_renamings_apart: "length (renamings_apart Cs) = length Cs" by (induction Cs) (auto simp: Let_def) lemma renamings_apart_is_Var: "\\ \ set (renamings_apart Cs). \x. is_Var (\ x)" by (induction Cs) (auto simp: Let_def) lemma renamings_apart_inj: "\\ \ set (renamings_apart Cs). inj \" proof (induction Cs) case (Cons a Cs) then have "inj (\v. Var (Suc (v + Max (vars_clause_list (subst_cls_lists Cs (renamings_apart Cs)) \ {0}))))" by (meson add_right_imp_eq injI nat.inject term.inject(1)) then show ?case using Cons by (auto simp: Let_def) qed auto lemma finite_vars_clause[simp]: "finite (vars_clause x)" unfolding vars_clause_def by auto lemma finite_vars_clause_list[simp]: "finite (vars_clause_list Cs)" unfolding vars_clause_list_def by (induction Cs) auto lemma Suc_Max_notin_set: "finite X \ Suc (v + Max (insert 0 X)) \ X" by (metis Max.boundedE Suc_n_not_le_n empty_iff finite.insertI le_add2 vimageE vimageI vimage_Suc_insert_0) lemma vars_partitioned_Nil[simp]: "vars_partitioned []" unfolding vars_partitioned_def by auto lemma subst_cls_lists_Nil[simp]: "subst_cls_lists Cs [] = []" unfolding subst_cls_lists_def by auto lemma vars_clause_hd_partitioned_from_tl: assumes "Cs \[]" shows "vars_clause (hd (subst_cls_lists Cs (renamings_apart Cs))) \ vars_clause_list (tl (subst_cls_lists Cs (renamings_apart Cs))) = {}" using assms proof (induction Cs) case (Cons C Cs) define \' :: "nat \ nat" where "\' = (\v. (Suc (v + Max ((vars_clause_list (subst_cls_lists Cs (renamings_apart Cs))) \ {0}))))" define \ :: "nat \ ('a, nat) term" where "\ = (\v. Var (\' v))" have "vars_clause (subst_cls C \) \ \ (vars_term ` range \)" using vars_in_instance_in_range_cls[of C "hd (renamings_apart (C # Cs))"] \_def \'_def by (auto simp: Let_def) moreover have "\ (vars_term ` range \) \ vars_clause_list (subst_cls_lists Cs (renamings_apart Cs)) = {}" proof - have "range \' \ vars_clause_list (subst_cls_lists Cs (renamings_apart Cs)) = {}" unfolding \'_def using Suc_Max_notin_set by auto then show ?thesis unfolding \_def \'_def by auto qed ultimately have "vars_clause (subst_cls C \) \ vars_clause_list (subst_cls_lists Cs (renamings_apart Cs)) = {}" by auto then show ?case unfolding \_def \'_def unfolding subst_cls_lists_def by (simp add: Let_def subst_cls_lists_def) qed auto lemma vars_partitioned_renamings_apart: "vars_partitioned (subst_cls_lists Cs (renamings_apart Cs))" proof (induction Cs) case (Cons C Cs) { fix i :: nat and j :: nat assume ij: "i < Suc (length Cs)" "j < i" have "vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! i) \ vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! j) = {}" proof (cases i; cases j) fix j' :: nat assume i'j': "i = 0" "j = Suc j'" then show "vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! i) \ vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! j) = {}" using ij by auto next fix i' :: nat assume i'j': "i = Suc i'" "j = 0" have disjoin_C_Cs: "vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! 0) \ vars_clause_list ((subst_cls_lists Cs (renamings_apart Cs))) = {}" using vars_clause_hd_partitioned_from_tl[of "C # Cs"] by (simp add: Let_def subst_cls_lists_def) { fix x assume asm: "x \ vars_clause (subst_cls_lists Cs (renamings_apart Cs) ! i')" then have "(subst_cls_lists Cs (renamings_apart Cs) ! i') \ set (subst_cls_lists Cs (renamings_apart Cs))" using i'j' ij unfolding subst_cls_lists_def by (metis Suc_less_SucD length_map len_renamings_apart length_zip min_less_iff_conj nth_mem) moreover from asm have "x \ vars_clause (subst_cls_lists Cs (renamings_apart Cs) ! i')" using i'j' ij unfolding subst_cls_lists_def by simp ultimately have "\D \ set (subst_cls_lists Cs (renamings_apart Cs)). x \ vars_clause D" by auto } then have "vars_clause (subst_cls_lists Cs (renamings_apart Cs) ! i') \ Union (set (map vars_clause ((subst_cls_lists Cs (renamings_apart Cs)))))" by auto then have "vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! 0) \ vars_clause (subst_cls_lists Cs (renamings_apart Cs) ! i') = {}" using disjoin_C_Cs unfolding vars_clause_list_def by auto moreover have "subst_cls_lists Cs (renamings_apart Cs) ! i' = subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! i" using i'j' ij unfolding subst_cls_lists_def by (simp add: Let_def) ultimately show "vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! i) \ vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! j) = {}" using i'j' by (simp add: Int_commute) next fix i' :: nat and j' :: nat assume i'j': "i = Suc i'" "j = Suc j'" have "i' j'" using \i = Suc i'\ \j = Suc j'\ ij by blast ultimately have "vars_clause (subst_cls_lists Cs (renamings_apart Cs) ! i') \ vars_clause (subst_cls_lists Cs (renamings_apart Cs) ! j') = {}" using Cons unfolding vars_partitioned_def by auto then show "vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! i) \ vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! j) = {}" unfolding i'j' by (simp add: subst_cls_lists_def Let_def) next assume \i = 0\ and \j = 0\ then show \vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! i) \ vars_clause (subst_cls_lists (C # Cs) (renamings_apart (C # Cs)) ! j) = {}\ using ij by auto qed } then show ?case unfolding vars_partitioned_def by (metis (no_types, lifting) Int_commute Suc_lessI len_renamings_apart length_map length_nth_simps(2) length_zip min.idem nat.inject not_less_eq subst_cls_lists_def) qed auto interpretation substitution "(\)" "Var :: _ \ ('f, nat) term" "(\\<^sub>s)" renamings_apart "Fun undefined" proof (standard) show "\A. A \ Var = A" by auto next show "\A \ \. A \ \ \\<^sub>s \ = A \ \ \ \" by auto next show "\\ \. (\A. A \ \ = A \ \) \ \ = \" by (simp add: subst_term_eqI) next fix C :: "('f, nat) term clause" fix \ assume "is_ground_cls (subst_cls C \)" then have ground_atms_\: "\v. v \ vars_clause C \ is_ground_atm (\ v)" by (meson is_ground_cls_is_ground_on_var) define some_ground_trm :: "('f, nat) term" where "some_ground_trm = (Fun undefined [])" have ground_trm: "is_ground_atm some_ground_trm" unfolding is_ground_atm_def some_ground_trm_def by auto define \ where "\ = (\v. if v \ vars_clause C then \ v else some_ground_trm)" then have \_\: "\v \ vars_clause C. \ v = \ v" unfolding \_def by auto have all_ground_\: "is_ground_atm (\ v)" for v proof (cases "v \ vars_clause C") case True then show ?thesis using ground_atms_\ \_\ by auto next case False then show ?thesis unfolding \_def using ground_trm by auto qed have "is_ground_subst \" unfolding is_ground_subst_def proof fix A show "is_ground_atm (subst_atm_abbrev A \)" proof (induction A) case (Var v) then show ?case using all_ground_\ by auto next case (Fun f As) then show ?case using all_ground_\ by (simp add: is_ground_atm_def) qed qed moreover have "\v \ vars_clause C. \ v = \ v" using \_\ unfolding vars_clause_list_def by blast then have "subst_cls C \ = subst_cls C \" using same_on_vars_clause by auto ultimately show "\\. is_ground_subst \ \ subst_cls C \ = subst_cls C \" by auto next fix Cs :: "('f, nat) term clause list" show "length (renamings_apart Cs) = length Cs" using len_renamings_apart by auto next fix Cs :: "('f, nat) term clause list" fix \ :: "nat \ ('f, nat) Term.term" assume \_renaming: "\ \ set (renamings_apart Cs)" { have inj_is_renaming: "\\ :: ('f, nat) subst. (\x. is_Var (\ x)) \ inj \ \ is_renaming \" proof - fix \ :: "('f, nat) subst" fix x assume is_var_\: "\x. is_Var (\ x)" assume inj_\: "inj \" define \' where "\' = var_map_of_subst \" have \: "\ = Var \ \'" unfolding \'_def var_map_of_subst_def using is_var_\ by auto from is_var_\ inj_\ have "inj \'" unfolding is_renaming_def unfolding subst_domain_def inj_on_def \'_def var_map_of_subst_def by (metis term.collapse(1)) then have "inv \' \ \' = id" using inv_o_cancel[of \'] by simp then have "Var \ (inv \' \ \') = Var" by simp then have "\x. (Var \ (inv \' \ \')) x = Var x" by metis then have "\x. ((Var \ \') \\<^sub>s (Var \ (inv \'))) x = Var x" unfolding subst_compose_def by auto then have "\ \\<^sub>s (Var \ (inv \')) = Var" using \ by auto then show "is_renaming \" unfolding is_renaming_def by blast qed then have "\\ \ (set (renamings_apart Cs)). is_renaming \" using renamings_apart_is_Var renamings_apart_inj by blast } then show "is_renaming \" using \_renaming by auto next fix Cs :: "('f, nat) term clause list" have "vars_partitioned (subst_cls_lists Cs (renamings_apart Cs))" using vars_partitioned_renamings_apart by auto then show "var_disjoint (subst_cls_lists Cs (renamings_apart Cs))" using vars_partitioned_var_disjoint by auto next show "\\ As Bs. Fun undefined As \ \ = Fun undefined Bs \ map (\A. A \ \) As = Bs" by simp next show "wfP (strictly_generalizes_atm :: ('f, 'v) term \ _ \ _)" unfolding wfP_def by (rule wf_subset[OF wf_subsumes]) (auto simp: strictly_generalizes_atm_def generalizes_atm_def term_subsumable.subsumes_def subsumeseq_term.simps) qed fun pairs :: "'a list \ ('a \ 'a) list" where "pairs (x # y # xs) = (x, y) # pairs (y # xs)" | "pairs _ = []" derive compare "term" derive compare "literal" lemma class_linorder_compare: "class.linorder (le_of_comp compare) (lt_of_comp compare)" apply standard apply (simp_all add: lt_of_comp_def le_of_comp_def split: order.splits) apply (metis comparator.sym comparator_compare invert_order.simps(1) order.distinct(5)) apply (metis comparator_compare comparator_def order.distinct(5)) apply (metis comparator.sym comparator_compare invert_order.simps(1) order.distinct(5)) by (metis comparator.sym comparator_compare invert_order.simps(2) order.distinct(5)) context begin interpretation compare_linorder: linorder "le_of_comp compare" "lt_of_comp compare" by (rule class_linorder_compare) definition Pairs where "Pairs AAA = concat (compare_linorder.sorted_list_of_set ((pairs \ compare_linorder.sorted_list_of_set) ` AAA))" lemma unifies_all_pairs_iff: "(\p \ set (pairs xs). fst p \ \ = snd p \ \) \ (\a \ set xs. \b \ set xs. a \ \ = b \ \)" proof (induct xs rule: pairs.induct) case (1 x y xs) then show ?case unfolding pairs.simps list.set ball_Un ball_simps simp_thms fst_conv snd_conv by metis qed simp_all lemma in_pair_in_set: assumes "(A,B) \ set ((pairs As))" shows "A \ set As \ B \ set As" using assms proof (induction As) case (Cons A As) note Cons_outer = this show ?case proof (cases As) case Nil then show ?thesis using Cons_outer by auto next case (Cons B As') then show ?thesis using Cons_outer by auto qed qed auto lemma in_pairs_sorted_list_of_set_in_set: assumes "finite AAA" "\AA \ AAA. finite AA" "AB_pairs \ (pairs \ compare_linorder.sorted_list_of_set) ` AAA" and "(A :: _ :: compare, B) \ set AB_pairs" shows "\AA. AA \ AAA \ A \ AA \ B \ AA" proof - from assms have "AB_pairs \ (pairs \ compare_linorder.sorted_list_of_set) ` AAA" by auto then obtain AA where AA_p: "AA \ AAA \ (pairs \ compare_linorder.sorted_list_of_set) AA = AB_pairs" by auto have "(A, B) \ set (pairs (compare_linorder.sorted_list_of_set AA))" using AA_p[] assms(4) by auto then have "A \ set (compare_linorder.sorted_list_of_set AA)" and "B \ set (compare_linorder.sorted_list_of_set AA)" using in_pair_in_set[of A] by auto then show ?thesis using assms(2) AA_p by auto qed lemma unifiers_Pairs: assumes "finite AAA" and "\AA \ AAA. finite AA" shows "unifiers (set (Pairs AAA)) = {\. is_unifiers \ AAA}" proof (rule; rule) fix \ :: "('a, 'b) subst" assume asm: "\ \ unifiers (set (Pairs AAA))" have "\AA. AA \ AAA \ card (AA \\<^sub>s\<^sub>e\<^sub>t \) \ Suc 0" proof - fix AA :: "('a, 'b) term set" assume asm': "AA \ AAA" then have "\p \ set (pairs (compare_linorder.sorted_list_of_set AA)). subst_atm_abbrev (fst p) \ = subst_atm_abbrev (snd p) \" using assms asm unfolding Pairs_def by auto then have "\A \ AA. \B \ AA. subst_atm_abbrev A \ = subst_atm_abbrev B \" using assms asm' unfolding unifies_all_pairs_iff using compare_linorder.sorted_list_of_set by blast then show "card (AA \\<^sub>s\<^sub>e\<^sub>t \) \ Suc 0" by (smt imageE card.empty card_Suc_eq card_mono finite.intros(1) finite_insert le_SucI singletonI subsetI) qed then show "\ \ {\. is_unifiers \ AAA}" using assms by (auto simp: is_unifiers_def is_unifier_def subst_atms_def) next fix \ :: "('a, 'b) subst" assume asm: "\ \ {\. is_unifiers \ AAA}" { fix AB_pairs A B assume "AB_pairs \ set (compare_linorder.sorted_list_of_set ((pairs \ compare_linorder.sorted_list_of_set) ` AAA))" and "(A, B) \ set AB_pairs" then have "\AA. AA \ AAA \ A \ AA \ B \ AA" using assms by (simp add: in_pairs_sorted_list_of_set_in_set) then obtain AA where a: "AA \ AAA" "A \ AA" "B \ AA" by blast from a assms asm have card_AA_\: "card (AA \\<^sub>s\<^sub>e\<^sub>t \) \ Suc 0" unfolding is_unifiers_def is_unifier_def subst_atms_def by auto have "subst_atm_abbrev A \ = subst_atm_abbrev B \" proof (cases "card (AA \\<^sub>s\<^sub>e\<^sub>t \) = Suc 0") case True moreover have "subst_atm_abbrev A \ \ AA \\<^sub>s\<^sub>e\<^sub>t \" using a assms asm card_AA_\ by auto moreover have "subst_atm_abbrev B \ \ AA \\<^sub>s\<^sub>e\<^sub>t \" using a assms asm card_AA_\ by auto ultimately show ?thesis using a assms asm card_AA_\ by (metis (no_types, lifting) card_Suc_eq singletonD) next case False then have "card (AA \\<^sub>s\<^sub>e\<^sub>t \) = 0" using a assms asm card_AA_\ by arith then show ?thesis using a assms asm card_AA_\ by auto qed } then show "\ \ unifiers (set (Pairs AAA))" unfolding Pairs_def unifiers_def by auto qed end definition "mgu_sets AAA = map_option subst_of (unify (Pairs AAA) [])" -interpretation mgu "(\)" "Var :: _ \ ('f :: compare, nat) term" "(\\<^sub>s)" "Fun undefined" - renamings_apart mgu_sets -proof +interpretation mgu "(\)" "Var :: _ \ ('f :: compare, nat) term" "(\\<^sub>s)" renamings_apart + "Fun undefined" mgu_sets +proof unfold_locales fix AAA :: "('a :: compare, nat) term set set" and \ :: "('a, nat) subst" assume fin: "finite AAA" "\AA \ AAA. finite AA" and "mgu_sets AAA = Some \" then have "is_imgu \ (set (Pairs AAA))" using unify_sound unfolding mgu_sets_def by blast then show "is_mgu \ AAA" unfolding is_imgu_def is_mgu_def unifiers_Pairs[OF fin] by auto next fix AAA :: "('a :: compare, nat) term set set" and \ :: "('a, nat) subst" assume fin: "finite AAA" "\AA \ AAA. finite AA" and "is_unifiers \ AAA" then have "\ \ unifiers (set (Pairs AAA))" unfolding is_mgu_def unifiers_Pairs[OF fin] by auto then show "\\. mgu_sets AAA = Some \" using unify_complete unfolding mgu_sets_def by blast qed derive linorder prod derive linorder list text \ This part extends and integrates and the Knuth--Bendix order defined in \textsf{IsaFoR}. \ record 'f weights = w :: "'f \ nat \ nat" w0 :: nat pr_strict :: "'f \ nat \ 'f \ nat \ bool" least :: "'f \ bool" scf :: "'f \ nat \ nat \ nat" class weighted = fixes weights :: "'a weights" assumes weights_adm: "admissible_kbo (w weights) (w0 weights) (pr_strict weights) ((pr_strict weights)\<^sup>=\<^sup>=) (least weights) (scf weights)" and pr_strict_total: "fi = gj \ pr_strict weights fi gj \ pr_strict weights gj fi" and pr_strict_asymp: "asymp (pr_strict weights)" and scf_ok: "i < n \ scf weights (f, n) i \ 1" instantiation unit :: weighted begin definition weights_unit :: "unit weights" where "weights_unit = \w = Suc \ snd, w0 = 1, pr_strict = \(_, n) (_, m). n > m, least = \_. True, scf = \_ _. 1\" instance by (intro_classes, unfold_locales) (auto simp: weights_unit_def SN_iff_wf asymp.simps irreflp_def intro!: wf_subset[OF wf_inv_image[OF wf], of _ snd]) end global_interpretation KBO: admissible_kbo "w (weights :: 'f :: weighted weights)" "w0 (weights :: 'f :: weighted weights)" "pr_strict weights" "((pr_strict weights)\<^sup>=\<^sup>=)" "least weights" "scf weights" defines weight = KBO.weight and kbo = KBO.kbo by (simp add: weights_adm) lemma kbo_code[code]: "kbo s t = (let wt = weight t; ws = weight s in if vars_term_ms (KBO.SCF t) \# vars_term_ms (KBO.SCF s) \ wt \ ws then (if wt < ws then (True, True) else (case s of Var y \ (False, case t of Var x \ True | Fun g ts \ ts = [] \ least weights g) | Fun f ss \ (case t of Var x \ (True, True) | Fun g ts \ if pr_strict weights (f, length ss) (g, length ts) then (True, True) else if (f, length ss) = (g, length ts) then lex_ext_unbounded kbo ss ts else (False, False)))) else (False, False))" by (subst KBO.kbo.simps) (auto simp: Let_def split: term.splits) definition "less_kbo s t = fst (kbo t s)" lemma less_kbo_gtotal: "ground s \ ground t \ s = t \ less_kbo s t \ less_kbo t s" unfolding less_kbo_def using KBO.S_ground_total by (metis pr_strict_total subset_UNIV) lemma less_kbo_subst: fixes \ :: "('f :: weighted, 'v) subst" shows "less_kbo s t \ less_kbo (s \ \) (t \ \)" unfolding less_kbo_def by (rule KBO.S_subst) lemma wfP_less_kbo: "wfP less_kbo" proof - have "SN {(x, y). fst (kbo x y)}" using pr_strict_asymp by (fastforce simp: asymp.simps irreflp_def intro!: KBO.S_SN scf_ok) then show ?thesis unfolding SN_iff_wf wfP_def by (rule wf_subset) (auto simp: less_kbo_def) qed instantiation "term" :: (weighted, type) linorder begin definition "leq_term = (SOME leq. {(s,t). less_kbo s t} \ leq \ Well_order leq \ Field leq = UNIV)" lemma less_trm_extension: "{(s,t). less_kbo s t} \ leq_term" unfolding leq_term_def by (rule someI2_ex[OF total_well_order_extension[OF wfP_less_kbo[unfolded wfP_def]]]) auto lemma less_trm_well_order: "well_order leq_term" unfolding leq_term_def by (rule someI2_ex[OF total_well_order_extension[OF wfP_less_kbo[unfolded wfP_def]]]) auto definition less_eq_term :: "('a :: weighted, 'b) term \ _ \ bool" where "less_eq_term = in_rel leq_term" definition less_term :: "('a :: weighted, 'b) term \ _ \ bool" where "less_term s t = strict (\) s t" lemma leq_term_minus_Id: "leq_term - Id = {(x,y). x < y}" using less_trm_well_order unfolding well_order_on_def linear_order_on_def partial_order_on_def antisym_def less_term_def less_eq_term_def by auto lemma less_term_alt: "(<) = in_rel (leq_term - Id)" by (simp add: in_rel_Collect_case_prod_eq leq_term_minus_Id) instance proof (standard, goal_cases less_less_eq refl trans antisym total) case (less_less_eq x y) then show ?case unfolding less_term_def .. next case (refl x) then show ?case using less_trm_well_order unfolding well_order_on_def linear_order_on_def partial_order_on_def preorder_on_def refl_on_def less_eq_term_def by auto next case (trans x y z) then show ?case using less_trm_well_order unfolding well_order_on_def linear_order_on_def partial_order_on_def preorder_on_def trans_def less_eq_term_def by auto next case (antisym x y) then show ?case using less_trm_well_order unfolding well_order_on_def linear_order_on_def partial_order_on_def antisym_def less_eq_term_def by auto next case (total x y) then show ?case using less_trm_well_order unfolding well_order_on_def linear_order_on_def partial_order_on_def preorder_on_def refl_on_def Relation.total_on_def less_eq_term_def by (cases "x = y") auto qed end instantiation "term" :: (weighted, type) wellorder begin instance using less_trm_well_order[unfolded well_order_on_def wf_def leq_term_minus_Id, THEN conjunct2] by intro_classes (atomize, auto) end lemma ground_less_less_kbo: "ground s \ ground t \ s < t \ less_kbo s t" using less_kbo_gtotal[of s t] less_trm_extension by (auto simp: less_term_def less_eq_term_def) lemma less_kbo_less: "less_kbo s t \ s < t" using less_trm_extension by (auto simp: less_term_alt less_kbo_def KBO.S_irrefl) lemma is_ground_atm_ground: "is_ground_atm t \ ground t" unfolding is_ground_atm_def by (induct t) (fastforce simp: in_set_conv_nth list_eq_iff_nth_eq)+ end diff --git a/thys/Ordered_Resolution_Prover/Abstract_Substitution.thy b/thys/Ordered_Resolution_Prover/Abstract_Substitution.thy --- a/thys/Ordered_Resolution_Prover/Abstract_Substitution.thy +++ b/thys/Ordered_Resolution_Prover/Abstract_Substitution.thy @@ -1,1271 +1,1271 @@ (* Title: Abstract Substitutions Author: Dmitriy Traytel , 2014 Author: Jasmin Blanchette , 2014, 2017 Author: Anders Schlichtkrull , 2016, 2017 Maintainer: Anders Schlichtkrull *) section \Abstract Substitutions\ theory Abstract_Substitution imports Clausal_Logic Map2 begin text \ Atoms and substitutions are abstracted away behind some locales, to avoid having a direct dependency on the IsaFoR library. Conventions: \'s\ substitutions, \'a\ atoms. \ subsection \Library\ lemma f_Suc_decr_eventually_const: fixes f :: "nat \ nat" assumes leq: "\i. f (Suc i) \ f i" shows "\l. \l' \ l. f l' = f (Suc l')" proof (rule ccontr) assume a: "\l. \l' \ l. f l' = f (Suc l')" have "\i. \i'. i' > i \ f i' < f i" proof fix i from a have "\l' \ i. f l' \ f (Suc l')" by auto then obtain l' where l'_p: "l' \ i \ f l' \ f (Suc l')" by metis then have "f l' > f (Suc l')" using leq le_eq_less_or_eq by auto moreover have "f i \ f l'" using leq l'_p by (induction l' arbitrary: i) (blast intro: lift_Suc_antimono_le)+ ultimately show "\i' > i. f i' < f i" using l'_p less_le_trans by blast qed then obtain g_sm :: "nat \ nat" where g_sm_p: "\i. g_sm i > i \ f (g_sm i) < f i" by metis define c :: "nat \ nat" where "\n. c n = (g_sm ^^ n) 0" have "f (c i) > f (c (Suc i))" for i by (induction i) (auto simp: c_def g_sm_p) then have "\i. (f \ c) i > (f \ c) (Suc i)" by auto then have "\fc :: nat \ nat. \i. fc i > fc (Suc i)" by metis then show False using wf_less_than by (simp add: wf_iff_no_infinite_down_chain) qed subsection \Substitution Operators\ locale substitution_ops = fixes subst_atm :: "'a \ 's \ 'a" and id_subst :: 's and comp_subst :: "'s \ 's \ 's" begin abbreviation subst_atm_abbrev :: "'a \ 's \ 'a" (infixl "\a" 67) where "subst_atm_abbrev \ subst_atm" abbreviation comp_subst_abbrev :: "'s \ 's \ 's" (infixl "\" 67) where "comp_subst_abbrev \ comp_subst" definition comp_substs :: "'s list \ 's list \ 's list" (infixl "\s" 67) where "\s \s \s = map2 comp_subst \s \s" definition subst_atms :: "'a set \ 's \ 'a set" (infixl "\as" 67) where "AA \as \ = (\A. A \a \) ` AA" definition subst_atmss :: "'a set set \ 's \ 'a set set" (infixl "\ass" 67) where "AAA \ass \ = (\AA. AA \as \) ` AAA" definition subst_atm_list :: "'a list \ 's \ 'a list" (infixl "\al" 67) where "As \al \ = map (\A. A \a \) As" definition subst_atm_mset :: "'a multiset \ 's \ 'a multiset" (infixl "\am" 67) where "AA \am \ = image_mset (\A. A \a \) AA" definition subst_atm_mset_list :: "'a multiset list \ 's \ 'a multiset list" (infixl "\aml" 67) where "AAA \aml \ = map (\AA. AA \am \) AAA" definition subst_atm_mset_lists :: "'a multiset list \ 's list \ 'a multiset list" (infixl "\\aml" 67) where "AAs \\aml \s = map2 (\am) AAs \s" definition subst_lit :: "'a literal \ 's \ 'a literal" (infixl "\l" 67) where "L \l \ = map_literal (\A. A \a \) L" lemma atm_of_subst_lit[simp]: "atm_of (L \l \) = atm_of L \a \" unfolding subst_lit_def by (cases L) simp+ definition subst_cls :: "'a clause \ 's \ 'a clause" (infixl "\" 67) where "AA \ \ = image_mset (\A. A \l \) AA" definition subst_clss :: "'a clause set \ 's \ 'a clause set" (infixl "\cs" 67) where "AA \cs \ = (\A. A \ \) ` AA" definition subst_cls_list :: "'a clause list \ 's \ 'a clause list" (infixl "\cl" 67) where "Cs \cl \ = map (\A. A \ \) Cs" definition subst_cls_lists :: "'a clause list \ 's list \ 'a clause list" (infixl "\\cl" 67) where "Cs \\cl \s = map2 (\) Cs \s" definition subst_cls_mset :: "'a clause multiset \ 's \ 'a clause multiset" (infixl "\cm" 67) where "CC \cm \ = image_mset (\A. A \ \) CC" lemma subst_cls_add_mset[simp]: "add_mset L C \ \ = add_mset (L \l \) (C \ \)" unfolding subst_cls_def by simp lemma subst_cls_mset_add_mset[simp]: "add_mset C CC \cm \ = add_mset (C \ \) (CC \cm \)" unfolding subst_cls_mset_def by simp definition generalizes_atm :: "'a \ 'a \ bool" where "generalizes_atm A B \ (\\. A \a \ = B)" definition strictly_generalizes_atm :: "'a \ 'a \ bool" where "strictly_generalizes_atm A B \ generalizes_atm A B \ \ generalizes_atm B A" definition generalizes_lit :: "'a literal \ 'a literal \ bool" where "generalizes_lit L M \ (\\. L \l \ = M)" definition strictly_generalizes_lit :: "'a literal \ 'a literal \ bool" where "strictly_generalizes_lit L M \ generalizes_lit L M \ \ generalizes_lit M L" definition generalizes :: "'a clause \ 'a clause \ bool" where "generalizes C D \ (\\. C \ \ = D)" definition strictly_generalizes :: "'a clause \ 'a clause \ bool" where "strictly_generalizes C D \ generalizes C D \ \ generalizes D C" definition subsumes :: "'a clause \ 'a clause \ bool" where "subsumes C D \ (\\. C \ \ \# D)" definition strictly_subsumes :: "'a clause \ 'a clause \ bool" where "strictly_subsumes C D \ subsumes C D \ \ subsumes D C" definition variants :: "'a clause \ 'a clause \ bool" where "variants C D \ generalizes C D \ generalizes D C" definition is_renaming :: "'s \ bool" where "is_renaming \ \ (\\. \ \ \ = id_subst)" definition is_renaming_list :: "'s list \ bool" where "is_renaming_list \s \ (\\ \ set \s. is_renaming \)" definition inv_renaming :: "'s \ 's" where "inv_renaming \ = (SOME \. \ \ \ = id_subst)" definition is_ground_atm :: "'a \ bool" where "is_ground_atm A \ (\\. A = A \a \)" definition is_ground_atms :: "'a set \ bool" where "is_ground_atms AA = (\A \ AA. is_ground_atm A)" definition is_ground_atm_list :: "'a list \ bool" where "is_ground_atm_list As \ (\A \ set As. is_ground_atm A)" definition is_ground_atm_mset :: "'a multiset \ bool" where "is_ground_atm_mset AA \ (\A. A \# AA \ is_ground_atm A)" definition is_ground_lit :: "'a literal \ bool" where "is_ground_lit L \ is_ground_atm (atm_of L)" definition is_ground_cls :: "'a clause \ bool" where "is_ground_cls C \ (\L. L \# C \ is_ground_lit L)" definition is_ground_clss :: "'a clause set \ bool" where "is_ground_clss CC \ (\C \ CC. is_ground_cls C)" definition is_ground_cls_list :: "'a clause list \ bool" where "is_ground_cls_list CC \ (\C \ set CC. is_ground_cls C)" definition is_ground_subst :: "'s \ bool" where "is_ground_subst \ \ (\A. is_ground_atm (A \a \))" definition is_ground_subst_list :: "'s list \ bool" where "is_ground_subst_list \s \ (\\ \ set \s. is_ground_subst \)" definition grounding_of_cls :: "'a clause \ 'a clause set" where "grounding_of_cls C = {C \ \ |\. is_ground_subst \}" definition grounding_of_clss :: "'a clause set \ 'a clause set" where "grounding_of_clss CC = (\C \ CC. grounding_of_cls C)" definition is_unifier :: "'s \ 'a set \ bool" where "is_unifier \ AA \ card (AA \as \) \ 1" definition is_unifiers :: "'s \ 'a set set \ bool" where "is_unifiers \ AAA \ (\AA \ AAA. is_unifier \ AA)" definition is_mgu :: "'s \ 'a set set \ bool" where "is_mgu \ AAA \ is_unifiers \ AAA \ (\\. is_unifiers \ AAA \ (\\. \ = \ \ \))" definition var_disjoint :: "'a clause list \ bool" where "var_disjoint Cs \ (\\s. length \s = length Cs \ (\\. \i < length Cs. \S. S \# Cs ! i \ S \ \s ! i = S \ \))" end subsection \Substitution Lemmas\ locale substitution = substitution_ops subst_atm id_subst comp_subst for subst_atm :: "'a \ 's \ 'a" and id_subst :: 's and comp_subst :: "'s \ 's \ 's" + fixes renamings_apart :: "'a clause list \ 's list" and atm_of_atms :: "'a list \ 'a" assumes subst_atm_id_subst[simp]: "A \a id_subst = A" and subst_atm_comp_subst[simp]: "A \a (\ \ \) = (A \a \) \a \" and subst_ext: "(\A. A \a \ = A \a \) \ \ = \" and make_ground_subst: "is_ground_cls (C \ \) \ \\. is_ground_subst \ \C \ \ = C \ \" and wf_strictly_generalizes_atm: "wfP strictly_generalizes_atm" and renamings_apart_length: "length (renamings_apart Cs) = length Cs" and renamings_apart_renaming: "\ \ set (renamings_apart Cs) \ is_renaming \" and renamings_apart_var_disjoint: "var_disjoint (Cs \\cl (renamings_apart Cs))" and atm_of_atms_subst: "\As Bs. atm_of_atms As \a \ = atm_of_atms Bs \ map (\A. A \a \) As = Bs" begin lemma subst_ext_iff: "\ = \ \ (\A. A \a \ = A \a \)" by (blast intro: subst_ext) subsubsection \Identity Substitution\ lemma id_subst_comp_subst[simp]: "id_subst \ \ = \" by (rule subst_ext) simp lemma comp_subst_id_subst[simp]: "\ \ id_subst = \" by (rule subst_ext) simp lemma id_subst_comp_substs[simp]: "replicate (length \s) id_subst \s \s = \s" using comp_substs_def by (induction \s) auto lemma comp_substs_id_subst[simp]: "\s \s replicate (length \s) id_subst = \s" using comp_substs_def by (induction \s) auto lemma subst_atms_id_subst[simp]: "AA \as id_subst = AA" unfolding subst_atms_def by simp lemma subst_atmss_id_subst[simp]: "AAA \ass id_subst = AAA" unfolding subst_atmss_def by simp lemma subst_atm_list_id_subst[simp]: "As \al id_subst = As" unfolding subst_atm_list_def by auto lemma subst_atm_mset_id_subst[simp]: "AA \am id_subst = AA" unfolding subst_atm_mset_def by simp lemma subst_atm_mset_list_id_subst[simp]: "AAs \aml id_subst = AAs" unfolding subst_atm_mset_list_def by simp lemma subst_atm_mset_lists_id_subst[simp]: "AAs \\aml replicate (length AAs) id_subst = AAs" unfolding subst_atm_mset_lists_def by (induct AAs) auto lemma subst_lit_id_subst[simp]: "L \l id_subst = L" unfolding subst_lit_def by (simp add: literal.map_ident) lemma subst_cls_id_subst[simp]: "C \ id_subst = C" unfolding subst_cls_def by simp lemma subst_clss_id_subst[simp]: "CC \cs id_subst = CC" unfolding subst_clss_def by simp lemma subst_cls_list_id_subst[simp]: "Cs \cl id_subst = Cs" unfolding subst_cls_list_def by simp lemma subst_cls_lists_id_subst[simp]: "Cs \\cl replicate (length Cs) id_subst = Cs" unfolding subst_cls_lists_def by (induct Cs) auto lemma subst_cls_mset_id_subst[simp]: "CC \cm id_subst = CC" unfolding subst_cls_mset_def by simp subsubsection \Associativity of Composition\ lemma comp_subst_assoc[simp]: "\ \ (\ \ \) = \ \ \ \ \" by (rule subst_ext) simp subsubsection \Compatibility of Substitution and Composition\ lemma subst_atms_comp_subst[simp]: "AA \as (\ \ \) = AA \as \ \as \" unfolding subst_atms_def by auto lemma subst_atmss_comp_subst[simp]: "AAA \ass (\ \ \) = AAA \ass \ \ass \" unfolding subst_atmss_def by auto lemma subst_atm_list_comp_subst[simp]: "As \al (\ \ \) = As \al \ \al \" unfolding subst_atm_list_def by auto lemma subst_atm_mset_comp_subst[simp]: "AA \am (\ \ \) = AA \am \ \am \" unfolding subst_atm_mset_def by auto lemma subst_atm_mset_list_comp_subst[simp]: "AAs \aml (\ \ \) = (AAs \aml \) \aml \" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_comp_substs[simp]: "AAs \\aml (\s \s \s) = AAs \\aml \s \\aml \s" unfolding subst_atm_mset_lists_def comp_substs_def map_zip_map map_zip_map2 map_zip_assoc by (simp add: split_def) lemma subst_lit_comp_subst[simp]: "L \l (\ \ \) = L \l \ \l \" unfolding subst_lit_def by (auto simp: literal.map_comp o_def) lemma subst_cls_comp_subst[simp]: "C \ (\ \ \) = C \ \ \ \" unfolding subst_cls_def by auto lemma subst_clsscomp_subst[simp]: "CC \cs (\ \ \) = CC \cs \ \cs \" unfolding subst_clss_def by auto lemma subst_cls_list_comp_subst[simp]: "Cs \cl (\ \ \) = Cs \cl \ \cl \" unfolding subst_cls_list_def by auto lemma subst_cls_lists_comp_substs[simp]: "Cs \\cl (\s \s \s) = Cs \\cl \s \\cl \s" unfolding subst_cls_lists_def comp_substs_def map_zip_map map_zip_map2 map_zip_assoc by (simp add: split_def) lemma subst_cls_mset_comp_subst[simp]: "CC \cm (\ \ \) = CC \cm \ \cm \" unfolding subst_cls_mset_def by auto subsubsection \``Commutativity'' of Membership and Substitution\ lemma Melem_subst_atm_mset[simp]: "A \# AA \am \ \ (\B. B \# AA \ A = B \a \)" unfolding subst_atm_mset_def by auto lemma Melem_subst_cls[simp]: "L \# C \ \ \ (\M. M \# C \ L = M \l \)" unfolding subst_cls_def by auto lemma Melem_subst_cls_mset[simp]: "AA \# CC \cm \ \ (\BB. BB \# CC \ AA = BB \ \)" unfolding subst_cls_mset_def by auto subsubsection \Signs and Substitutions\ lemma subst_lit_is_neg[simp]: "is_neg (L \l \) = is_neg L" unfolding subst_lit_def by auto lemma subst_lit_is_pos[simp]: "is_pos (L \l \) = is_pos L" unfolding subst_lit_def by auto lemma subst_minus[simp]: "(- L) \l \ = - (L \l \)" by (simp add: literal.map_sel subst_lit_def uminus_literal_def) subsubsection \Substitution on Literal(s)\ lemma eql_neg_lit_eql_atm[simp]: "(Neg A' \l \) = Neg A \ A' \a \ = A" by (simp add: subst_lit_def) lemma eql_pos_lit_eql_atm[simp]: "(Pos A' \l \) = Pos A \ A' \a \ = A" by (simp add: subst_lit_def) lemma subst_cls_negs[simp]: "(negs AA) \ \ = negs (AA \am \)" unfolding subst_cls_def subst_lit_def subst_atm_mset_def by auto lemma subst_cls_poss[simp]: "(poss AA) \ \ = poss (AA \am \)" unfolding subst_cls_def subst_lit_def subst_atm_mset_def by auto lemma atms_of_subst_atms: "atms_of C \as \ = atms_of (C \ \)" proof - have "atms_of (C \ \) = set_mset (image_mset atm_of (image_mset (map_literal (\A. A \a \)) C))" unfolding subst_cls_def subst_atms_def subst_lit_def atms_of_def by auto also have "... = set_mset (image_mset (\A. A \a \) (image_mset atm_of C))" by simp (meson literal.map_sel) finally show "atms_of C \as \ = atms_of (C \ \)" unfolding subst_atms_def atms_of_def by auto qed lemma in_image_Neg_is_neg[simp]: "L \l \ \ Neg ` AA \ is_neg L" by (metis bex_imageD literal.disc(2) literal.map_disc_iff subst_lit_def) lemma subst_lit_in_negs_subst_is_neg: "L \l \ \# (negs AA) \ \ \ is_neg L" by simp lemma subst_lit_in_negs_is_neg: "L \l \ \# negs AA \ is_neg L" by simp subsubsection \Substitution on Empty\ lemma subst_atms_empty[simp]: "{} \as \ = {}" unfolding subst_atms_def by auto lemma subst_atmss_empty[simp]: "{} \ass \ = {}" unfolding subst_atmss_def by auto lemma comp_substs_empty_iff[simp]: "\s \s \s = [] \ \s = [] \ \s = []" using comp_substs_def map2_empty_iff by auto lemma subst_atm_list_empty[simp]: "[] \al \ = []" unfolding subst_atm_list_def by auto lemma subst_atm_mset_empty[simp]: "{#} \am \ = {#}" unfolding subst_atm_mset_def by auto lemma subst_atm_mset_list_empty[simp]: "[] \aml \ = []" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_empty[simp]: "[] \\aml \s = []" unfolding subst_atm_mset_lists_def by auto lemma subst_cls_empty[simp]: "{#} \ \ = {#}" unfolding subst_cls_def by auto lemma subst_clss_empty[simp]: "{} \cs \ = {}" unfolding subst_clss_def by auto lemma subst_cls_list_empty[simp]: "[] \cl \ = []" unfolding subst_cls_list_def by auto lemma subst_cls_lists_empty[simp]: "[] \\cl \s = []" unfolding subst_cls_lists_def by auto lemma subst_scls_mset_empty[simp]: "{#} \cm \ = {#}" unfolding subst_cls_mset_def by auto lemma subst_atms_empty_iff[simp]: "AA \as \ = {} \ AA = {}" unfolding subst_atms_def by auto lemma subst_atmss_empty_iff[simp]: "AAA \ass \ = {} \ AAA = {}" unfolding subst_atmss_def by auto lemma subst_atm_list_empty_iff[simp]: "As \al \ = [] \ As = []" unfolding subst_atm_list_def by auto lemma subst_atm_mset_empty_iff[simp]: "AA \am \ = {#} \ AA = {#}" unfolding subst_atm_mset_def by auto lemma subst_atm_mset_list_empty_iff[simp]: "AAs \aml \ = [] \ AAs = []" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_empty_iff[simp]: "AAs \\aml \s = [] \ (AAs = [] \ \s = [])" using map2_empty_iff subst_atm_mset_lists_def by auto lemma subst_cls_empty_iff[simp]: "C \ \ = {#} \ C = {#}" unfolding subst_cls_def by auto lemma subst_clss_empty_iff[simp]: "CC \cs \ = {} \ CC = {}" unfolding subst_clss_def by auto lemma subst_cls_list_empty_iff[simp]: "Cs \cl \ = [] \ Cs = []" unfolding subst_cls_list_def by auto lemma subst_cls_lists_empty_iff[simp]: "Cs \\cl \s = [] \ Cs = [] \ \s = []" using map2_empty_iff subst_cls_lists_def by auto lemma subst_cls_mset_empty_iff[simp]: "CC \cm \ = {#} \ CC = {#}" unfolding subst_cls_mset_def by auto subsubsection \Substitution on a Union\ lemma subst_atms_union[simp]: "(AA \ BB) \as \ = AA \as \ \ BB \as \" unfolding subst_atms_def by auto lemma subst_atmss_union[simp]: "(AAA \ BBB) \ass \ = AAA \ass \ \ BBB \ass \" unfolding subst_atmss_def by auto lemma subst_atm_list_append[simp]: "(As @ Bs) \al \ = As \al \ @ Bs \al \" unfolding subst_atm_list_def by auto lemma subst_atm_mset_union[simp]: "(AA + BB) \am \ = AA \am \ + BB \am \" unfolding subst_atm_mset_def by auto lemma subst_atm_mset_list_append[simp]: "(AAs @ BBs) \aml \ = AAs \aml \ @ BBs \aml \" unfolding subst_atm_mset_list_def by auto lemma subst_cls_union[simp]: "(C + D) \ \ = C \ \ + D \ \" unfolding subst_cls_def by auto lemma subst_clss_union[simp]: "(CC \ DD) \cs \ = CC \cs \ \ DD \cs \" unfolding subst_clss_def by auto lemma subst_cls_list_append[simp]: "(Cs @ Ds) \cl \ = Cs \cl \ @ Ds \cl \" unfolding subst_cls_list_def by auto lemma subst_cls_lists_append[simp]: "length Cs = length \s \ length Cs' = length \s' \ (Cs @ Cs') \\cl (\s @ \s') = Cs \\cl \s @ Cs' \\cl \s'" unfolding subst_cls_lists_def by auto lemma subst_cls_mset_union[simp]: "(CC + DD) \cm \ = CC \cm \ + DD \cm \" unfolding subst_cls_mset_def by auto subsubsection \Substitution on a Singleton\ lemma subst_atms_single[simp]: "{A} \as \ = {A \a \}" unfolding subst_atms_def by auto lemma subst_atmss_single[simp]: "{AA} \ass \ = {AA \as \}" unfolding subst_atmss_def by auto lemma subst_atm_list_single[simp]: "[A] \al \ = [A \a \]" unfolding subst_atm_list_def by auto lemma subst_atm_mset_single[simp]: "{#A#} \am \ = {#A \a \#}" unfolding subst_atm_mset_def by auto lemma subst_atm_mset_list[simp]: "[AA] \aml \ = [AA \am \]" unfolding subst_atm_mset_list_def by auto lemma subst_cls_single[simp]: "{#L#} \ \ = {#L \l \#}" by simp lemma subst_clss_single[simp]: "{C} \cs \ = {C \ \}" unfolding subst_clss_def by auto lemma subst_cls_list_single[simp]: "[C] \cl \ = [C \ \]" unfolding subst_cls_list_def by auto lemma subst_cls_lists_single[simp]: "[C] \\cl [\] = [C \ \]" unfolding subst_cls_lists_def by auto lemma subst_cls_mset_single[simp]: "{#C#} \cm \ = {#C \ \#}" by simp subsubsection \Substitution on @{term Cons}\ lemma subst_atm_list_Cons[simp]: "(A # As) \al \ = A \a \ # As \al \" unfolding subst_atm_list_def by auto lemma subst_atm_mset_list_Cons[simp]: "(A # As) \aml \ = A \am \ # As \aml \" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_Cons[simp]: "(C # Cs) \\aml (\ # \s) = C \am \ # Cs \\aml \s" unfolding subst_atm_mset_lists_def by auto lemma subst_cls_list_Cons[simp]: "(C # Cs) \cl \ = C \ \ # Cs \cl \" unfolding subst_cls_list_def by auto lemma subst_cls_lists_Cons[simp]: "(C # Cs) \\cl (\ # \s) = C \ \ # Cs \\cl \s" unfolding subst_cls_lists_def by auto subsubsection \Substitution on @{term tl}\ lemma subst_atm_list_tl[simp]: "tl (As \al \) = tl As \al \" by (cases As) auto lemma subst_atm_mset_list_tl[simp]: "tl (AAs \aml \) = tl AAs \aml \" by (cases AAs) auto lemma subst_cls_list_tl[simp]: "tl (Cs \cl \) = tl Cs \cl \" by (cases Cs) auto lemma subst_cls_lists_tl[simp]: "length Cs = length \s \ tl (Cs \\cl \s) = tl Cs \\cl tl \s" by (cases Cs; cases \s) auto subsubsection \Substitution on @{term nth}\ lemma comp_substs_nth[simp]: "length \s = length \s \ i < length \s \ (\s \s \s) ! i = (\s ! i) \ (\s ! i)" by (simp add: comp_substs_def) lemma subst_atm_list_nth[simp]: "i < length As \ (As \al \) ! i = As ! i \a \" unfolding subst_atm_list_def using less_Suc_eq_0_disj nth_map by force lemma subst_atm_mset_list_nth[simp]: "i < length AAs \ (AAs \aml \) ! i = (AAs ! i) \am \" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_nth[simp]: "length AAs = length \s \ i < length AAs \ (AAs \\aml \s) ! i = (AAs ! i) \am (\s ! i)" unfolding subst_atm_mset_lists_def by auto lemma subst_cls_list_nth[simp]: "i < length Cs \ (Cs \cl \) ! i = (Cs ! i) \ \" unfolding subst_cls_list_def using less_Suc_eq_0_disj nth_map by (induction Cs) auto lemma subst_cls_lists_nth[simp]: "length Cs = length \s \ i < length Cs \ (Cs \\cl \s) ! i = (Cs ! i) \ (\s ! i)" unfolding subst_cls_lists_def by auto subsubsection \Substitution on Various Other Functions\ lemma subst_clss_image[simp]: "image f X \cs \ = {f x \ \ | x. x \ X}" unfolding subst_clss_def by auto lemma subst_cls_mset_image_mset[simp]: "image_mset f X \cm \ = {# f x \ \. x \# X #}" unfolding subst_cls_mset_def by auto lemma mset_subst_atm_list_subst_atm_mset[simp]: "mset (As \al \) = mset (As) \am \" unfolding subst_atm_list_def subst_atm_mset_def by auto lemma mset_subst_cls_list_subst_cls_mset: "mset (Cs \cl \) = (mset Cs) \cm \" unfolding subst_cls_mset_def subst_cls_list_def by auto lemma sum_list_subst_cls_list_subst_cls[simp]: "sum_list (Cs \cl \) = sum_list Cs \ \" unfolding subst_cls_list_def by (induction Cs) auto lemma set_mset_subst_cls_mset_subst_clss: "set_mset (CC \cm \) = (set_mset CC) \cs \" by (simp add: subst_cls_mset_def subst_clss_def) lemma Neg_Melem_subst_atm_subst_cls[simp]: "Neg A \# C \ Neg (A \a \) \# C \ \ " by (metis Melem_subst_cls eql_neg_lit_eql_atm) lemma Pos_Melem_subst_atm_subst_cls[simp]: "Pos A \# C \ Pos (A \a \) \# C \ \ " by (metis Melem_subst_cls eql_pos_lit_eql_atm) lemma in_atms_of_subst[simp]: "B \ atms_of C \ B \a \ \ atms_of (C \ \)" by (metis atms_of_subst_atms image_iff subst_atms_def) subsubsection \Renamings\ lemma is_renaming_id_subst[simp]: "is_renaming id_subst" unfolding is_renaming_def by simp lemma is_renamingD: "is_renaming \ \ (\A1 A2. A1 \a \ = A2 \a \ \ A1 = A2)" by (metis is_renaming_def subst_atm_comp_subst subst_atm_id_subst) lemma inv_renaming_cancel_r[simp]: "is_renaming r \ r \ inv_renaming r = id_subst" unfolding inv_renaming_def is_renaming_def by (metis (mono_tags) someI_ex) lemma inv_renaming_cancel_r_list[simp]: "is_renaming_list rs \ rs \s map inv_renaming rs = replicate (length rs) id_subst" unfolding is_renaming_list_def by (induction rs) (auto simp add: comp_substs_def) lemma Nil_comp_substs[simp]: "[] \s s = []" unfolding comp_substs_def by auto lemma comp_substs_Nil[simp]: "s \s [] = []" unfolding comp_substs_def by auto lemma is_renaming_idempotent_id_subst: "is_renaming r \ r \ r = r \ r = id_subst" by (metis comp_subst_assoc comp_subst_id_subst inv_renaming_cancel_r) lemma is_renaming_left_id_subst_right_id_subst: "is_renaming r \ s \ r = id_subst \ r \ s = id_subst" by (metis comp_subst_assoc comp_subst_id_subst is_renaming_def) lemma is_renaming_closure: "is_renaming r1 \ is_renaming r2 \ is_renaming (r1 \ r2)" unfolding is_renaming_def by (metis comp_subst_assoc comp_subst_id_subst) lemma is_renaming_inv_renaming_cancel_atm[simp]: "is_renaming \ \ A \a \ \a inv_renaming \ = A" by (metis inv_renaming_cancel_r subst_atm_comp_subst subst_atm_id_subst) lemma is_renaming_inv_renaming_cancel_atms[simp]: "is_renaming \ \ AA \as \ \as inv_renaming \ = AA" by (metis inv_renaming_cancel_r subst_atms_comp_subst subst_atms_id_subst) lemma is_renaming_inv_renaming_cancel_atmss[simp]: "is_renaming \ \ AAA \ass \ \ass inv_renaming \ = AAA" by (metis inv_renaming_cancel_r subst_atmss_comp_subst subst_atmss_id_subst) lemma is_renaming_inv_renaming_cancel_atm_list[simp]: "is_renaming \ \ As \al \ \al inv_renaming \ = As" by (metis inv_renaming_cancel_r subst_atm_list_comp_subst subst_atm_list_id_subst) lemma is_renaming_inv_renaming_cancel_atm_mset[simp]: "is_renaming \ \ AA \am \ \am inv_renaming \ = AA" by (metis inv_renaming_cancel_r subst_atm_mset_comp_subst subst_atm_mset_id_subst) lemma is_renaming_inv_renaming_cancel_atm_mset_list[simp]: "is_renaming \ \ (AAs \aml \) \aml inv_renaming \ = AAs" by (metis inv_renaming_cancel_r subst_atm_mset_list_comp_subst subst_atm_mset_list_id_subst) lemma is_renaming_list_inv_renaming_cancel_atm_mset_lists[simp]: "length AAs = length \s \ is_renaming_list \s \ AAs \\aml \s \\aml map inv_renaming \s = AAs" by (metis inv_renaming_cancel_r_list subst_atm_mset_lists_comp_substs subst_atm_mset_lists_id_subst) lemma is_renaming_inv_renaming_cancel_lit[simp]: "is_renaming \ \ (L \l \) \l inv_renaming \ = L" by (metis inv_renaming_cancel_r subst_lit_comp_subst subst_lit_id_subst) lemma is_renaming_inv_renaming_cancel_cls[simp]: "is_renaming \ \ C \ \ \ inv_renaming \ = C" by (metis inv_renaming_cancel_r subst_cls_comp_subst subst_cls_id_subst) lemma is_renaming_inv_renaming_cancel_clss[simp]: "is_renaming \ \ CC \cs \ \cs inv_renaming \ = CC" by (metis inv_renaming_cancel_r subst_clss_id_subst subst_clsscomp_subst) lemma is_renaming_inv_renaming_cancel_cls_list[simp]: "is_renaming \ \ Cs \cl \ \cl inv_renaming \ = Cs" by (metis inv_renaming_cancel_r subst_cls_list_comp_subst subst_cls_list_id_subst) lemma is_renaming_list_inv_renaming_cancel_cls_list[simp]: "length Cs = length \s \ is_renaming_list \s \ Cs \\cl \s \\cl map inv_renaming \s = Cs" by (metis inv_renaming_cancel_r_list subst_cls_lists_comp_substs subst_cls_lists_id_subst) lemma is_renaming_inv_renaming_cancel_cls_mset[simp]: "is_renaming \ \ CC \cm \ \cm inv_renaming \ = CC" by (metis inv_renaming_cancel_r subst_cls_mset_comp_subst subst_cls_mset_id_subst) subsubsection \Monotonicity\ lemma subst_cls_mono: "set_mset C \ set_mset D \ set_mset (C \ \) \ set_mset (D \ \)" by force lemma subst_cls_mono_mset: "C \# D \ C \ \ \# D \ \" unfolding subst_clss_def by (metis mset_subset_eq_exists_conv subst_cls_union) lemma subst_subset_mono: "D \# C \ D \ \ \# C \ \" unfolding subst_cls_def by (simp add: image_mset_subset_mono) subsubsection \Size after Substitution\ lemma size_subst[simp]: "size (D \ \) = size D" unfolding subst_cls_def by auto lemma subst_atm_list_length[simp]: "length (As \al \) = length As" unfolding subst_atm_list_def by auto lemma length_subst_atm_mset_list[simp]: "length (AAs \aml \) = length AAs" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_length[simp]: "length (AAs \\aml \s) = min (length AAs) (length \s)" unfolding subst_atm_mset_lists_def by auto lemma subst_cls_list_length[simp]: "length (Cs \cl \) = length Cs" unfolding subst_cls_list_def by auto lemma comp_substs_length[simp]: "length (\s \s \s) = min (length \s) (length \s)" unfolding comp_substs_def by auto lemma subst_cls_lists_length[simp]: "length (Cs \\cl \s) = min (length Cs) (length \s)" unfolding subst_cls_lists_def by auto subsubsection \Variable Disjointness\ lemma var_disjoint_clauses: assumes "var_disjoint Cs" shows "\\s. length \s = length Cs \ (\\. Cs \\cl \s = Cs \cl \)" proof clarify fix \s :: "'s list" assume a: "length \s = length Cs" then obtain \ where "\i < length Cs. \S. S \# Cs ! i \ S \ \s ! i = S \ \" using assms unfolding var_disjoint_def by blast then have "\i < length Cs. (Cs ! i) \ \s ! i = (Cs ! i) \ \" by auto then have "Cs \\cl \s = Cs \cl \" using a by (auto intro: nth_equalityI) then show "\\. Cs \\cl \s = Cs \cl \" by auto qed subsubsection \Ground Expressions and Substitutions\ lemma ex_ground_subst: "\\. is_ground_subst \" using make_ground_subst[of "{#}"] by (simp add: is_ground_cls_def) lemma is_ground_cls_list_Cons[simp]: "is_ground_cls_list (C # Cs) = (is_ground_cls C \ is_ground_cls_list Cs)" unfolding is_ground_cls_list_def by auto paragraph \Ground union\ lemma is_ground_atms_union[simp]: "is_ground_atms (AA \ BB) \ is_ground_atms AA \ is_ground_atms BB" unfolding is_ground_atms_def by auto lemma is_ground_atm_mset_union[simp]: "is_ground_atm_mset (AA + BB) \ is_ground_atm_mset AA \ is_ground_atm_mset BB" unfolding is_ground_atm_mset_def by auto lemma is_ground_cls_union[simp]: "is_ground_cls (C + D) \ is_ground_cls C \ is_ground_cls D" unfolding is_ground_cls_def by auto lemma is_ground_clss_union[simp]: "is_ground_clss (CC \ DD) \ is_ground_clss CC \ is_ground_clss DD" unfolding is_ground_clss_def by auto lemma is_ground_cls_list_is_ground_cls_sum_list[simp]: "is_ground_cls_list Cs \ is_ground_cls (sum_list Cs)" by (meson in_mset_sum_list2 is_ground_cls_def is_ground_cls_list_def) paragraph \Grounding monotonicity\ lemma is_ground_cls_mono: "C \# D \ is_ground_cls D \ is_ground_cls C" unfolding is_ground_cls_def by (metis set_mset_mono subsetD) lemma is_ground_clss_mono: "CC \ DD \ is_ground_clss DD \ is_ground_clss CC" unfolding is_ground_clss_def by blast lemma grounding_of_clss_mono: "CC \ DD \ grounding_of_clss CC \ grounding_of_clss DD" using grounding_of_clss_def by auto lemma sum_list_subseteq_mset_is_ground_cls_list[simp]: "sum_list Cs \# sum_list Ds \ is_ground_cls_list Ds \ is_ground_cls_list Cs" by (meson in_mset_sum_list is_ground_cls_def is_ground_cls_list_is_ground_cls_sum_list is_ground_cls_mono is_ground_cls_list_def) paragraph \Substituting on ground expression preserves ground\ lemma is_ground_comp_subst[simp]: "is_ground_subst \ \ is_ground_subst (\ \ \)" unfolding is_ground_subst_def is_ground_atm_def by auto lemma ground_subst_ground_atm[simp]: "is_ground_subst \ \ is_ground_atm (A \a \)" by (simp add: is_ground_subst_def) lemma ground_subst_ground_lit[simp]: "is_ground_subst \ \ is_ground_lit (L \l \)" unfolding is_ground_lit_def subst_lit_def by (cases L) auto lemma ground_subst_ground_cls[simp]: "is_ground_subst \ \ is_ground_cls (C \ \)" unfolding is_ground_cls_def by auto lemma ground_subst_ground_clss[simp]: "is_ground_subst \ \ is_ground_clss (CC \cs \)" unfolding is_ground_clss_def subst_clss_def by auto lemma ground_subst_ground_cls_list[simp]: "is_ground_subst \ \ is_ground_cls_list (Cs \cl \)" unfolding is_ground_cls_list_def subst_cls_list_def by auto lemma ground_subst_ground_cls_lists[simp]: "\\ \ set \s. is_ground_subst \ \ is_ground_cls_list (Cs \\cl \s)" unfolding is_ground_cls_list_def subst_cls_lists_def by (auto simp: set_zip) lemma subst_cls_eq_grounding_of_cls_subset_eq: assumes "D \ \ = C" shows "grounding_of_cls C \ grounding_of_cls D" proof fix C\' assume "C\' \ grounding_of_cls C" then obtain \' where C\': "C \ \' = C\'" "is_ground_subst \'" unfolding grounding_of_cls_def by auto then have "C \ \' = D \ \ \ \' \ is_ground_subst (\ \ \')" using assms by auto then show "C\' \ grounding_of_cls D" unfolding grounding_of_cls_def using C\'(1) by force qed paragraph \Substituting on ground expression has no effect\ lemma is_ground_subst_atm[simp]: "is_ground_atm A \ A \a \ = A" unfolding is_ground_atm_def by simp lemma is_ground_subst_atms[simp]: "is_ground_atms AA \ AA \as \ = AA" unfolding is_ground_atms_def subst_atms_def image_def by auto lemma is_ground_subst_atm_mset[simp]: "is_ground_atm_mset AA \ AA \am \ = AA" unfolding is_ground_atm_mset_def subst_atm_mset_def by auto lemma is_ground_subst_atm_list[simp]: "is_ground_atm_list As \ As \al \ = As" unfolding is_ground_atm_list_def subst_atm_list_def by (auto intro: nth_equalityI) lemma is_ground_subst_atm_list_member[simp]: "is_ground_atm_list As \ i < length As \ As ! i \a \ = As ! i" unfolding is_ground_atm_list_def by auto lemma is_ground_subst_lit[simp]: "is_ground_lit L \ L \l \ = L" unfolding is_ground_lit_def subst_lit_def by (cases L) simp_all lemma is_ground_subst_cls[simp]: "is_ground_cls C \ C \ \ = C" unfolding is_ground_cls_def subst_cls_def by simp lemma is_ground_subst_clss[simp]: "is_ground_clss CC \ CC \cs \ = CC" unfolding is_ground_clss_def subst_clss_def image_def by auto lemma is_ground_subst_cls_lists[simp]: assumes "length P = length Cs" and "is_ground_cls_list Cs" shows "Cs \\cl P = Cs" using assms by (metis is_ground_cls_list_def is_ground_subst_cls min.idem nth_equalityI nth_mem subst_cls_lists_nth subst_cls_lists_length) lemma is_ground_subst_lit_iff: "is_ground_lit L \ (\\. L = L \l \)" using is_ground_atm_def is_ground_lit_def subst_lit_def by (cases L) auto lemma is_ground_subst_cls_iff: "is_ground_cls C \ (\\. C = C \ \)" by (metis ex_ground_subst ground_subst_ground_cls is_ground_subst_cls) paragraph \Members of ground expressions are ground\ lemma is_ground_cls_as_atms: "is_ground_cls C \ (\A \ atms_of C. is_ground_atm A)" by (auto simp: atms_of_def is_ground_cls_def is_ground_lit_def) lemma is_ground_cls_imp_is_ground_lit: "L \# C \ is_ground_cls C \ is_ground_lit L" by (simp add: is_ground_cls_def) lemma is_ground_cls_imp_is_ground_atm: "A \ atms_of C \ is_ground_cls C \ is_ground_atm A" by (simp add: is_ground_cls_as_atms) lemma is_ground_cls_is_ground_atms_atms_of[simp]: "is_ground_cls C \ is_ground_atms (atms_of C)" by (simp add: is_ground_cls_imp_is_ground_atm is_ground_atms_def) lemma grounding_ground: "C \ grounding_of_clss M \ is_ground_cls C" unfolding grounding_of_clss_def grounding_of_cls_def by auto lemma in_subset_eq_grounding_of_clss_is_ground_cls[simp]: "C \ CC \ CC \ grounding_of_clss DD \ is_ground_cls C" unfolding grounding_of_clss_def grounding_of_cls_def by auto lemma is_ground_cls_empty[simp]: "is_ground_cls {#}" unfolding is_ground_cls_def by simp lemma grounding_of_cls_ground: "is_ground_cls C \ grounding_of_cls C = {C}" unfolding grounding_of_cls_def by (simp add: ex_ground_subst) lemma grounding_of_cls_empty[simp]: "grounding_of_cls {#} = {{#}}" by (simp add: grounding_of_cls_ground) lemma union_grounding_of_cls_ground: "is_ground_clss (\ (grounding_of_cls ` N))" by (simp add: grounding_ground grounding_of_clss_def is_ground_clss_def) paragraph \Grounding idempotence\ lemma grounding_of_grounding_of_cls: "E \ grounding_of_cls D \ D \ grounding_of_cls C \ E = D" using grounding_of_cls_def by auto subsubsection \Subsumption\ lemma subsumes_empty_left[simp]: "subsumes {#} C" unfolding subsumes_def subst_cls_def by simp lemma strictly_subsumes_empty_left[simp]: "strictly_subsumes {#} C \ C \ {#}" unfolding strictly_subsumes_def subsumes_def subst_cls_def by simp subsubsection \Unifiers\ lemma card_le_one_alt: "finite X \ card X \ 1 \ X = {} \ (\x. X = {x})" by (induct rule: finite_induct) auto lemma is_unifier_subst_atm_eqI: assumes "finite AA" shows "is_unifier \ AA \ A \ AA \ B \ AA \ A \a \ = B \a \" unfolding is_unifier_def subst_atms_def card_le_one_alt[OF finite_imageI[OF assms]] by (metis equals0D imageI insert_iff) lemma is_unifier_alt: assumes "finite AA" shows "is_unifier \ AA \ (\A \ AA. \B \ AA. A \a \ = B \a \)" unfolding is_unifier_def subst_atms_def card_le_one_alt[OF finite_imageI[OF assms(1)]] by (rule iffI, metis empty_iff insert_iff insert_image, blast) lemma is_unifiers_subst_atm_eqI: assumes "finite AA" "is_unifiers \ AAA" "AA \ AAA" "A \ AA" "B \ AA" shows "A \a \ = B \a \" by (metis assms is_unifiers_def is_unifier_subst_atm_eqI) theorem is_unifiers_comp: "is_unifiers \ (set_mset ` set (map2 add_mset As Bs) \ass \) \ is_unifiers (\ \ \) (set_mset ` set (map2 add_mset As Bs))" unfolding is_unifiers_def is_unifier_def subst_atmss_def by auto subsubsection \Most General Unifier\ lemma is_mgu_is_unifiers: "is_mgu \ AAA \ is_unifiers \ AAA" using is_mgu_def by blast lemma is_mgu_is_most_general: "is_mgu \ AAA \ is_unifiers \ AAA \ \\. \ = \ \ \" using is_mgu_def by blast lemma is_unifiers_is_unifier: "is_unifiers \ AAA \ AA \ AAA \ is_unifier \ AA" using is_unifiers_def by simp subsubsection \Generalization and Subsumption\ lemma variants_sym: "variants D D' \ variants D' D" unfolding variants_def by auto lemma variants_iff_subsumes: "variants C D \ subsumes C D \ subsumes D C" proof assume "variants C D" then show "subsumes C D \ subsumes D C" unfolding variants_def generalizes_def subsumes_def by (metis subset_mset.refl) next assume sub: "subsumes C D \ subsumes D C" then have "size C = size D" unfolding subsumes_def by (metis antisym size_mset_mono size_subst) then show "variants C D" using sub unfolding subsumes_def variants_def generalizes_def by (metis leD mset_subset_size size_mset_mono size_subst subset_mset.not_eq_order_implies_strict) qed lemma wf_strictly_generalizes: "wfP strictly_generalizes" proof - { assume "\C_at. \i. strictly_generalizes (C_at (Suc i)) (C_at i)" then obtain C_at :: "nat \ 'a clause" where sg_C: "\i. strictly_generalizes (C_at (Suc i)) (C_at i)" by blast define n :: nat where "n = size (C_at 0)" have sz_C: "size (C_at i) = n" for i proof (induct i) case (Suc i) then show ?case using sg_C[of i] unfolding strictly_generalizes_def generalizes_def subst_cls_def by (metis size_image_mset) qed (simp add: n_def) obtain \_at :: "nat \ 's" where C_\: "\i. image_mset (\L. L \l \_at i) (C_at (Suc i)) = C_at i" using sg_C[unfolded strictly_generalizes_def generalizes_def subst_cls_def] by metis define Ls_at :: "nat \ 'a literal list" where "Ls_at = rec_nat (SOME Ls. mset Ls = C_at 0) (\i Lsi. SOME Ls. mset Ls = C_at (Suc i) \ map (\L. L \l \_at i) Ls = Lsi)" have Ls_at_0: "Ls_at 0 = (SOME Ls. mset Ls = C_at 0)" and Ls_at_Suc: "\i. Ls_at (Suc i) = (SOME Ls. mset Ls = C_at (Suc i) \ map (\L. L \l \_at i) Ls = Ls_at i)" unfolding Ls_at_def by simp+ have mset_Lt_at_0: "mset (Ls_at 0) = C_at 0" unfolding Ls_at_0 by (rule someI_ex) (metis list_of_mset_exi) have "mset (Ls_at (Suc i)) = C_at (Suc i) \ map (\L. L \l \_at i) (Ls_at (Suc i)) = Ls_at i" for i proof (induct i) case 0 then show ?case by (simp add: Ls_at_Suc, rule someI_ex, metis C_\ image_mset_of_subset_list mset_Lt_at_0) next case Suc then show ?case by (subst (1 2) Ls_at_Suc) (rule someI_ex, metis C_\ image_mset_of_subset_list) qed note mset_Ls = this[THEN conjunct1] and Ls_\ = this[THEN conjunct2] have len_Ls: "\i. length (Ls_at i) = n" by (metis mset_Ls mset_Lt_at_0 not0_implies_Suc size_mset sz_C) have is_pos_Ls: "\i j. j < n \ is_pos (Ls_at (Suc i) ! j) \ is_pos (Ls_at i ! j)" using Ls_\ len_Ls by (metis literal.map_disc_iff nth_map subst_lit_def) have Ls_\_strict_lit: "\i \. map (\L. L \l \) (Ls_at i) \ Ls_at (Suc i)" by (metis C_\ mset_Ls Ls_\ mset_map sg_C generalizes_def strictly_generalizes_def subst_cls_def) have Ls_\_strict_tm: "map ((\t. t \a \) \ atm_of) (Ls_at i) \ map atm_of (Ls_at (Suc i))" for i \ proof - obtain j :: nat where j_lt: "j < n" and j_\: "Ls_at i ! j \l \ \ Ls_at (Suc i) ! j" using Ls_\_strict_lit[of \ i] len_Ls by (metis (no_types, lifting) length_map list_eq_iff_nth_eq nth_map) have "atm_of (Ls_at i ! j) \a \ \ atm_of (Ls_at (Suc i) ! j)" using j_\ is_pos_Ls[OF j_lt] by (metis (mono_guards) literal.expand literal.map_disc_iff literal.map_sel subst_lit_def) then show ?thesis using j_lt len_Ls by (metis nth_map o_apply) qed define tm_at :: "nat \ 'a" where "\i. tm_at i = atm_of_atms (map atm_of (Ls_at i))" have "\i. generalizes_atm (tm_at (Suc i)) (tm_at i)" unfolding tm_at_def generalizes_atm_def atm_of_atms_subst using Ls_\[THEN arg_cong, of "map atm_of"] by (auto simp: comp_def) moreover have "\i. \ generalizes_atm (tm_at i) (tm_at (Suc i))" unfolding tm_at_def generalizes_atm_def atm_of_atms_subst by (simp add: Ls_\_strict_tm) ultimately have "\i. strictly_generalizes_atm (tm_at (Suc i)) (tm_at i)" unfolding strictly_generalizes_atm_def by blast then have False using wf_strictly_generalizes_atm[unfolded wfP_def wf_iff_no_infinite_down_chain] by blast } then show "wfP (strictly_generalizes :: 'a clause \ _ \ _)" unfolding wfP_def by (blast intro: wf_iff_no_infinite_down_chain[THEN iffD2]) qed lemma strict_subset_subst_strictly_subsumes: "C \ \ \# D \ strictly_subsumes C D" by (metis leD mset_subset_size size_mset_mono size_subst strictly_subsumes_def subset_mset.dual_order.strict_implies_order substitution_ops.subsumes_def) lemma generalizes_refl: "generalizes C C" unfolding generalizes_def by (rule exI[of _ id_subst]) auto lemma generalizes_trans: "generalizes C D \ generalizes D E \ generalizes C E" unfolding generalizes_def using subst_cls_comp_subst by blast lemma subsumes_refl: "subsumes C C" unfolding subsumes_def by (rule exI[of _ id_subst]) auto lemma subsumes_trans: "subsumes C D \ subsumes D E \ subsumes C E" unfolding subsumes_def by (metis (no_types) subset_mset.trans subst_cls_comp_subst subst_cls_mono_mset) lemma strictly_generalizes_irrefl: "\ strictly_generalizes C C" unfolding strictly_generalizes_def by blast lemma strictly_generalizes_antisym: "strictly_generalizes C D \ \ strictly_generalizes D C" unfolding strictly_generalizes_def by blast lemma strictly_generalizes_trans: "strictly_generalizes C D \ strictly_generalizes D E \ strictly_generalizes C E" unfolding strictly_generalizes_def using generalizes_trans by blast lemma strictly_subsumes_irrefl: "\ strictly_subsumes C C" unfolding strictly_subsumes_def by blast lemma strictly_subsumes_antisym: "strictly_subsumes C D \ \ strictly_subsumes D C" unfolding strictly_subsumes_def by blast lemma strictly_subsumes_trans: "strictly_subsumes C D \ strictly_subsumes D E \ strictly_subsumes C E" unfolding strictly_subsumes_def using subsumes_trans by blast lemma subset_strictly_subsumes: "C \# D \ strictly_subsumes C D" using strict_subset_subst_strictly_subsumes[of C id_subst] by auto lemma strictly_generalizes_neq: "strictly_generalizes D' D \ D' \ D \ \" unfolding strictly_generalizes_def generalizes_def by blast lemma strictly_subsumes_neq: "strictly_subsumes D' D \ D' \ D \ \" unfolding strictly_subsumes_def subsumes_def by blast lemma strictly_subsumes_has_minimum: assumes "CC \ {}" shows "\C \ CC. \D \ CC. \ strictly_subsumes D C" proof (rule ccontr) assume "\ (\C \ CC. \D\CC. \ strictly_subsumes D C)" then have "\C \ CC. \D \ CC. strictly_subsumes D C" by blast then obtain f where f_p: "\C \ CC. f C \ CC \ strictly_subsumes (f C) C" by metis from assms obtain C where C_p: "C \ CC" by auto define c :: "nat \ 'a clause" where "\n. c n = (f ^^ n) C" have incc: "c i \ CC" for i by (induction i) (auto simp: c_def f_p C_p) have ps: "\i. strictly_subsumes (c (Suc i)) (c i)" using incc f_p unfolding c_def by auto have "\i. size (c i) \ size (c (Suc i))" using ps unfolding strictly_subsumes_def subsumes_def by (metis size_mset_mono size_subst) then have lte: "\i. (size \ c) i \ (size \ c) (Suc i)" unfolding comp_def . then have "\l. \l' \ l. size (c l') = size (c (Suc l'))" using f_Suc_decr_eventually_const comp_def by auto then obtain l where l_p: "\l' \ l. size (c l') = size (c (Suc l'))" by metis then have "\l' \ l. strictly_generalizes (c (Suc l')) (c l')" using ps unfolding strictly_generalizes_def generalizes_def by (metis size_subst less_irrefl strictly_subsumes_def mset_subset_size subset_mset_def subsumes_def strictly_subsumes_neq) then have "\i. strictly_generalizes (c (Suc i + l)) (c (i + l))" unfolding strictly_generalizes_def generalizes_def by auto then have "\f. \i. strictly_generalizes (f (Suc i)) (f i)" by (rule exI[of _ "\x. c (x + l)"]) then show False using wf_strictly_generalizes wf_iff_no_infinite_down_chain[of "{(x, y). strictly_generalizes x y}"] unfolding wfP_def by auto qed lemma wf_strictly_subsumes: "wfP strictly_subsumes" using strictly_subsumes_has_minimum by (metis equals0D wfP_eq_minimal) lemma variants_imp_exists_substitution: "variants D D' \ \\. D \ \ = D'" unfolding variants_iff_subsumes subsumes_def by (meson strictly_subsumes_def subset_mset_def strict_subset_subst_strictly_subsumes subsumes_def) lemma strictly_subsumes_variants: assumes "strictly_subsumes E D" and "variants D D'" shows "strictly_subsumes E D'" proof - from assms obtain \ \' where \_\'_p: "D \ \ = D' \ D' \ \' = D" using variants_imp_exists_substitution variants_sym by metis from assms obtain \'' where "E \ \'' \# D" unfolding strictly_subsumes_def subsumes_def by auto then have "E \ \'' \ \ \# D \ \" using subst_cls_mono_mset by blast then have "E \ (\'' \ \) \# D'" using \_\'_p by auto moreover from assms have n: "\\. D \ \ \# E" unfolding strictly_subsumes_def subsumes_def by auto have "\\. D' \ \ \# E" proof assume "\\'''. D' \ \''' \# E" then obtain \''' where "D' \ \''' \# E" by auto then have "D \ (\ \ \''') \# E" using \_\'_p by auto then show False using n by metis qed ultimately show ?thesis unfolding strictly_subsumes_def subsumes_def by metis qed lemma neg_strictly_subsumes_variants: assumes "\ strictly_subsumes E D" and "variants D D'" shows "\ strictly_subsumes E D'" using assms strictly_subsumes_variants variants_sym by auto end subsection \Most General Unifiers\ locale mgu = substitution subst_atm id_subst comp_subst renamings_apart atm_of_atms for subst_atm :: "'a \ 's \ 'a" and id_subst :: 's and comp_subst :: "'s \ 's \ 's" and - atm_of_atms :: "'a list \ 'a" and - renamings_apart :: "'a literal multiset list \ 's list" + + renamings_apart :: "'a literal multiset list \ 's list" and + atm_of_atms :: "'a list \ 'a"+ fixes mgu :: "'a set set \ 's option" assumes mgu_sound: "finite AAA \ (\AA \ AAA. finite AA) \ mgu AAA = Some \ \ is_mgu \ AAA" and mgu_complete: "finite AAA \ (\AA \ AAA. finite AA) \ is_unifiers \ AAA \ \\. mgu AAA = Some \" begin lemmas is_unifiers_mgu = mgu_sound[unfolded is_mgu_def, THEN conjunct1] lemmas is_mgu_most_general = mgu_sound[unfolded is_mgu_def, THEN conjunct2] lemma mgu_unifier: assumes aslen: "length As = n" and aaslen: "length AAs = n" and mgu: "Some \ = mgu (set_mset ` set (map2 add_mset As AAs))" and i_lt: "i < n" and a_in: "A \# AAs ! i" shows "A \a \ = As ! i \a \" proof - from mgu have "is_mgu \ (set_mset ` set (map2 add_mset As AAs))" using mgu_sound by auto then have "is_unifiers \ (set_mset ` set (map2 add_mset As AAs))" using is_mgu_is_unifiers by auto then have "is_unifier \ (set_mset (add_mset (As ! i) (AAs ! i)))" using i_lt aslen aaslen unfolding is_unifiers_def is_unifier_def by simp (metis length_zip min.idem nth_mem nth_zip prod.case set_mset_add_mset_insert) then show ?thesis using aslen aaslen a_in is_unifier_subst_atm_eqI by (metis finite_set_mset insertCI set_mset_add_mset_insert) qed end end diff --git a/thys/Ordered_Resolution_Prover/FO_Ordered_Resolution.thy b/thys/Ordered_Resolution_Prover/FO_Ordered_Resolution.thy --- a/thys/Ordered_Resolution_Prover/FO_Ordered_Resolution.thy +++ b/thys/Ordered_Resolution_Prover/FO_Ordered_Resolution.thy @@ -1,1412 +1,1412 @@ (* Title: First-Order Ordered Resolution Calculus with Selection Author: Anders Schlichtkrull , 2016, 2017 Author: Jasmin Blanchette , 2014, 2017 Author: Dmitriy Traytel , 2014 Author: Sophie Tourret , 2020 Maintainer: Anders Schlichtkrull *) section \First-Order Ordered Resolution Calculus with Selection\ theory FO_Ordered_Resolution imports Abstract_Substitution Ordered_Ground_Resolution Standard_Redundancy begin text \ This material is based on Section 4.3 (``A Simple Resolution Prover for First-Order Clauses'') of Bachmair and Ganzinger's chapter. Specifically, it formalizes the ordered resolution calculus for first-order standard clauses presented in Figure 4 and its related lemmas and theorems, including soundness and Lemma 4.12 (the lifting lemma). The following corresponds to pages 41--42 of Section 4.3, until Figure 5 and its explanation. \ -locale FO_resolution = mgu subst_atm id_subst comp_subst atm_of_atms renamings_apart mgu +locale FO_resolution = mgu subst_atm id_subst comp_subst renamings_apart atm_of_atms mgu for subst_atm :: "'a :: wellorder \ 's \ 'a" and id_subst :: "'s" and comp_subst :: "'s \ 's \ 's" and renamings_apart :: "'a literal multiset list \ 's list" and atm_of_atms :: "'a list \ 'a" and mgu :: "'a set set \ 's option" + fixes less_atm :: "'a \ 'a \ bool" assumes less_atm_stable: "less_atm A B \ less_atm (A \a \) (B \a \)" and less_atm_ground: "is_ground_atm A \ is_ground_atm B \ less_atm A B \ A < B" begin subsection \Library\ lemma Bex_cartesian_product: "(\xy \ A \ B. P xy) \ (\x \ A. \y \ B. P (x, y))" by simp lemma eql_map_neg_lit_eql_atm: assumes "map (\L. L \l \) (map Neg As') = map Neg As" shows "As' \al \ = As" using assms by (induction As' arbitrary: As) auto lemma instance_list: assumes "negs (mset As) = SDA' \ \" shows "\As'. negs (mset As') = SDA' \ As' \al \ = As" proof - from assms have negL: "\L \# SDA'. is_neg L" using Melem_subst_cls subst_lit_in_negs_is_neg by metis from assms have "{#L \l \. L \# SDA'#} = mset (map Neg As)" using subst_cls_def by auto then have "\NAs'. map (\L. L \l \) NAs' = map Neg As \ mset NAs' = SDA'" using image_mset_of_subset_list[of "\L. L \l \" SDA' "map Neg As"] by auto then obtain As' where As'_p: "map (\L. L \l \) (map Neg As') = map Neg As \ mset (map Neg As') = SDA'" by (metis (no_types, lifting) Neg_atm_of_iff negL ex_map_conv set_mset_mset) have "negs (mset As') = SDA'" using As'_p by auto moreover have "map (\L. L \l \) (map Neg As') = map Neg As" using As'_p by auto then have "As' \al \ = As" using eql_map_neg_lit_eql_atm by auto ultimately show ?thesis by blast qed lemma map2_add_mset_map: assumes "length AAs' = n" and "length As' = n" shows "map2 add_mset (As' \al \) (AAs' \aml \) = map2 add_mset As' AAs' \aml \" using assms proof (induction n arbitrary: AAs' As') case (Suc n) then have "map2 add_mset (tl (As' \al \)) (tl (AAs' \aml \)) = map2 add_mset (tl As') (tl AAs') \aml \" by simp moreover have Succ: "length (As' \al \) = Suc n" "length (AAs' \aml \) = Suc n" using Suc(3) Suc(2) by auto then have "length (tl (As' \al \)) = n" "length (tl (AAs' \aml \)) = n" by auto then have "length (map2 add_mset (tl (As' \al \)) (tl (AAs' \aml \))) = n" "length (map2 add_mset (tl As') (tl AAs') \aml \) = n" using Suc(2,3) by auto ultimately have "\i < n. tl (map2 add_mset ( (As' \al \)) ((AAs' \aml \))) ! i = tl (map2 add_mset (As') (AAs') \aml \) ! i" using Suc(2,3) Succ by (simp add: map2_tl map_tl subst_atm_mset_list_def del: subst_atm_list_tl) moreover have nn: "length (map2 add_mset ((As' \al \)) ((AAs' \aml \))) = Suc n" "length (map2 add_mset (As') (AAs') \aml \) = Suc n" using Succ Suc by auto ultimately have "\i. i < Suc n \ i > 0 \ map2 add_mset (As' \al \) (AAs' \aml \) ! i = (map2 add_mset As' AAs' \aml \) ! i" by (auto simp: subst_atm_mset_list_def gr0_conv_Suc subst_atm_mset_def) moreover have "add_mset (hd As' \a \) (hd AAs' \am \) = add_mset (hd As') (hd AAs') \am \" unfolding subst_atm_mset_def by auto then have "(map2 add_mset (As' \al \) (AAs' \aml \)) ! 0 = (map2 add_mset (As') (AAs') \aml \) ! 0" using Suc by (simp add: Succ(2) subst_atm_mset_def) ultimately have "\i < Suc n. (map2 add_mset (As' \al \) (AAs' \aml \)) ! i = (map2 add_mset (As') (AAs') \aml \) ! i" using Suc by auto then show ?case using nn list_eq_iff_nth_eq by metis qed auto context fixes S :: "'a clause \ 'a clause" begin subsection \Calculus\ text \ The following corresponds to Figure 4. \ definition maximal_wrt :: "'a \ 'a literal multiset \ bool" where "maximal_wrt A C \ (\B \ atms_of C. \ less_atm A B)" definition strictly_maximal_wrt :: "'a \ 'a literal multiset \ bool" where "strictly_maximal_wrt A C \ \B \ atms_of C. A \ B \ \ less_atm A B" lemma strictly_maximal_wrt_maximal_wrt: "strictly_maximal_wrt A C \ maximal_wrt A C" unfolding maximal_wrt_def strictly_maximal_wrt_def by auto lemma maximal_wrt_subst: "maximal_wrt (A \a \) (C \ \) \ maximal_wrt A C" unfolding maximal_wrt_def using in_atms_of_subst less_atm_stable by blast lemma strictly_maximal_wrt_subst: "strictly_maximal_wrt (A \a \) (C \ \) \ strictly_maximal_wrt A C" unfolding strictly_maximal_wrt_def using in_atms_of_subst less_atm_stable by blast inductive eligible :: "'s \ 'a list \ 'a clause \ bool" where eligible: "S DA = negs (mset As) \ S DA = {#} \ length As = 1 \ maximal_wrt (As ! 0 \a \) (DA \ \) \ eligible \ As DA" inductive ord_resolve :: "'a clause list \ 'a clause \ 'a multiset list \ 'a list \ 's \ 'a clause \ bool" where ord_resolve: "length CAs = n \ length Cs = n \ length AAs = n \ length As = n \ n \ 0 \ (\i < n. CAs ! i = Cs ! i + poss (AAs ! i)) \ (\i < n. AAs ! i \ {#}) \ Some \ = mgu (set_mset ` set (map2 add_mset As AAs)) \ eligible \ As (D + negs (mset As)) \ (\i < n. strictly_maximal_wrt (As ! i \a \) (Cs ! i \ \)) \ (\i < n. S (CAs ! i) = {#}) \ ord_resolve CAs (D + negs (mset As)) AAs As \ ((\\<^sub># (mset Cs) + D) \ \)" inductive ord_resolve_rename :: "'a clause list \ 'a clause \ 'a multiset list \ 'a list \ 's \ 'a clause \ bool" where ord_resolve_rename: "length CAs = n \ length AAs = n \ length As = n \ (\i < n. poss (AAs ! i) \# CAs ! i) \ negs (mset As) \# DA \ \ = hd (renamings_apart (DA # CAs)) \ \s = tl (renamings_apart (DA # CAs)) \ ord_resolve (CAs \\cl \s) (DA \ \) (AAs \\aml \s) (As \al \) \ E \ ord_resolve_rename CAs DA AAs As \ E" lemma ord_resolve_empty_main_prem: "\ ord_resolve Cs {#} AAs As \ E" by (simp add: ord_resolve.simps) lemma ord_resolve_rename_empty_main_prem: "\ ord_resolve_rename Cs {#} AAs As \ E" by (simp add: ord_resolve_empty_main_prem ord_resolve_rename.simps) subsection \Soundness\ text \ Soundness is not discussed in the chapter, but it is an important property. \ lemma ord_resolve_ground_inst_sound: assumes res_e: "ord_resolve CAs DA AAs As \ E" and cc_inst_true: "I \m mset CAs \cm \ \cm \" and d_inst_true: "I \ DA \ \ \ \" and ground_subst_\: "is_ground_subst \" shows "I \ E \ \" using res_e proof (cases rule: ord_resolve.cases) case (ord_resolve n Cs D) note da = this(1) and e = this(2) and cas_len = this(3) and cs_len = this(4) and aas_len = this(5) and as_len = this(6) and cas = this(8) and mgu = this(10) and len = this(1) have len: "length CAs = length As" using as_len cas_len by auto have "is_ground_subst (\ \ \)" using ground_subst_\ by (rule is_ground_comp_subst) then have cc_true: "I \m mset CAs \cm \ \cm \" and d_true: "I \ DA \ \ \ \" using cc_inst_true d_inst_true by auto from mgu have unif: "\i < n. \A\#AAs ! i. A \a \ = As ! i \a \" using mgu_unifier as_len aas_len by blast show "I \ E \ \" proof (cases "\A \ set As. A \a \ \a \ \ I") case True then have "\ I \ negs (mset As) \ \ \ \" unfolding true_cls_def[of I] by auto then have "I \ D \ \ \ \" using d_true da by auto then show ?thesis unfolding e by auto next case False then obtain i where a_in_aa: "i < length CAs" and a_false: "(As ! i) \a \ \a \ \ I" using da len by (metis in_set_conv_nth) define C where "C \ Cs ! i" define BB where "BB \ AAs ! i" have c_cf': "C \# \\<^sub># (mset CAs)" unfolding C_def using a_in_aa cas cas_len by (metis less_subset_eq_Union_mset mset_subset_eq_add_left subset_mset.trans) have c_in_cc: "C + poss BB \# mset CAs" using C_def BB_def a_in_aa cas_len in_set_conv_nth cas by fastforce { fix B assume "B \# BB" then have "B \a \ = (As ! i) \a \" using unif a_in_aa cas_len unfolding BB_def by auto } then have "\ I \ poss BB \ \ \ \" using a_false by (auto simp: true_cls_def) moreover have "I \ (C + poss BB) \ \ \ \" using c_in_cc cc_true true_cls_mset_true_cls[of I "mset CAs \cm \ \cm \"] by force ultimately have "I \ C \ \ \ \" by simp then show ?thesis unfolding e subst_cls_union using c_cf' C_def a_in_aa cas_len cs_len by (metis (no_types, lifting) mset_subset_eq_add_left nth_mem_mset set_mset_mono sum_mset.remove true_cls_mono subst_cls_mono) qed qed text \ The previous lemma is not only used to prove soundness, but also the following lemma which is used to prove Lemma 4.10. \ lemma ord_resolve_rename_ground_inst_sound: assumes "ord_resolve_rename CAs DA AAs As \ E" and "\s = tl (renamings_apart (DA # CAs))" and "\ = hd (renamings_apart (DA # CAs))" and "I \m (mset (CAs \\cl \s)) \cm \ \cm \" and "I \ DA \ \ \ \ \ \" and "is_ground_subst \" shows "I \ E \ \" using assms by (cases rule: ord_resolve_rename.cases) (fast intro: ord_resolve_ground_inst_sound) text \ Here follows the soundness theorem for the resolution rule. \ theorem ord_resolve_sound: assumes res_e: "ord_resolve CAs DA AAs As \ E" and cc_d_true: "\\. is_ground_subst \ \ I \m (mset CAs + {#DA#}) \cm \" and ground_subst_\: "is_ground_subst \" shows "I \ E \ \" proof (use res_e in \cases rule: ord_resolve.cases\) case (ord_resolve n Cs D) note da = this(1) and e = this(2) and cas_len = this(3) and cs_len = this(4) and aas_len = this(5) and as_len = this(6) and cas = this(8) and mgu = this(10) have ground_subst_\_\: "is_ground_subst (\ \ \)" using ground_subst_\ by (rule is_ground_comp_subst) have cas_true: "I \m mset CAs \cm \ \cm \" using cc_d_true ground_subst_\_\ by fastforce have da_true: "I \ DA \ \ \ \" using cc_d_true ground_subst_\_\ by fastforce show "I \ E \ \" using ord_resolve_ground_inst_sound[OF res_e cas_true da_true] ground_subst_\ by auto qed lemma subst_sound: assumes "\\. is_ground_subst \ \ I \ C \ \" and "is_ground_subst \" shows "I \ C \ \ \ \" using assms is_ground_comp_subst subst_cls_comp_subst by metis lemma subst_sound_scl: assumes len: "length P = length CAs" and true_cas: "\\. is_ground_subst \ \ I \m mset CAs \cm \" and ground_subst_\: "is_ground_subst \" shows "I \m mset (CAs \\cl P) \cm \" proof - from true_cas have "\CA. CA\# mset CAs \ (\\. is_ground_subst \ \ I \ CA \ \)" unfolding true_cls_mset_def by force then have "\i < length CAs. \\. is_ground_subst \ \ (I \ CAs ! i \ \)" using in_set_conv_nth by auto then have true_cp: "\i < length CAs. \\. is_ground_subst \ \ I \ CAs ! i \ P ! i \ \" using subst_sound len by auto { fix CA assume "CA \# mset (CAs \\cl P)" then obtain i where i_x: "i < length (CAs \\cl P)" "CA = (CAs \\cl P) ! i" by (metis in_mset_conv_nth) then have "\\. is_ground_subst \ \ I \ CA \ \" using true_cp unfolding subst_cls_lists_def by (simp add: len) } then show ?thesis using assms unfolding true_cls_mset_def by auto qed text \ Here follows the soundness theorem for the resolution rule with renaming. \ lemma ord_resolve_rename_sound: assumes res_e: "ord_resolve_rename CAs DA AAs As \ E" and cc_d_true: "\\. is_ground_subst \ \ I \m ((mset CAs) + {#DA#}) \cm \" and ground_subst_\: "is_ground_subst \" shows "I \ E \ \" using res_e proof (cases rule: ord_resolve_rename.cases) case (ord_resolve_rename n \ \s) note \s = this(7) and res = this(8) have len: "length \s = length CAs" using \s renamings_apart_length by auto have "\\. is_ground_subst \ \ I \m (mset (CAs \\cl \s) + {#DA \ \#}) \cm \" using subst_sound_scl[OF len, of I] subst_sound cc_d_true by auto then show "I \ E \ \" using ground_subst_\ ord_resolve_sound[OF res] by simp qed subsection \Other Basic Properties\ lemma ord_resolve_unique: assumes "ord_resolve CAs DA AAs As \ E" and "ord_resolve CAs DA AAs As \' E'" shows "\ = \' \ E = E'" using assms proof (cases rule: ord_resolve.cases[case_product ord_resolve.cases], intro conjI) case (ord_resolve_ord_resolve CAs n Cs AAs As \'' DA CAs' n' Cs' AAs' As' \''' DA') note res = this(1-17) and res' = this(18-34) show \: "\ = \'" using res(3-5,14) res'(3-5,14) by (metis option.inject) have "Cs = Cs'" using res(1,3,7,8,12) res'(1,3,7,8,12) by (metis add_right_imp_eq nth_equalityI) moreover have "DA = DA'" using res(2,4) res'(2,4) by fastforce ultimately show "E = E'" using res(5,6) res'(5,6) \ by blast qed lemma ord_resolve_rename_unique: assumes "ord_resolve_rename CAs DA AAs As \ E" and "ord_resolve_rename CAs DA AAs As \' E'" shows "\ = \' \ E = E'" using assms unfolding ord_resolve_rename.simps using ord_resolve_unique by meson lemma ord_resolve_max_side_prems: "ord_resolve CAs DA AAs As \ E \ length CAs \ size DA" by (auto elim!: ord_resolve.cases) lemma ord_resolve_rename_max_side_prems: "ord_resolve_rename CAs DA AAs As \ E \ length CAs \ size DA" by (elim ord_resolve_rename.cases, drule ord_resolve_max_side_prems, simp add: renamings_apart_length) subsection \Inference System\ definition ord_FO_\ :: "'a inference set" where "ord_FO_\ = {Infer (mset CAs) DA E | CAs DA AAs As \ E. ord_resolve_rename CAs DA AAs As \ E}" interpretation ord_FO_resolution: inference_system ord_FO_\ . lemma finite_ord_FO_resolution_inferences_between: assumes fin_cc: "finite CC" shows "finite (ord_FO_resolution.inferences_between CC C)" proof - let ?CCC = "CC \ {C}" define all_AA where "all_AA = (\D \ ?CCC. atms_of D)" define max_ary where "max_ary = Max (size ` ?CCC)" define CAS where "CAS = {CAs. CAs \ lists ?CCC \ length CAs \ max_ary}" define AS where "AS = {As. As \ lists all_AA \ length As \ max_ary}" define AAS where "AAS = {AAs. AAs \ lists (mset ` AS) \ length AAs \ max_ary}" note defs = all_AA_def max_ary_def CAS_def AS_def AAS_def let ?infer_of = "\CAs DA AAs As. Infer (mset CAs) DA (THE E. \\. ord_resolve_rename CAs DA AAs As \ E)" let ?Z = "{\ | CAs DA AAs As \ E \. \ = Infer (mset CAs) DA E \ ord_resolve_rename CAs DA AAs As \ E \ infer_from ?CCC \ \ C \# prems_of \}" let ?Y = "{Infer (mset CAs) DA E | CAs DA AAs As \ E. ord_resolve_rename CAs DA AAs As \ E \ set CAs \ {DA} \ ?CCC}" let ?X = "{?infer_of CAs DA AAs As | CAs DA AAs As. CAs \ CAS \ DA \ ?CCC \ AAs \ AAS \ As \ AS}" let ?W = "CAS \ ?CCC \ AAS \ AS" have fin_w: "finite ?W" unfolding defs using fin_cc by (simp add: finite_lists_length_le lists_eq_set) have "?Z \ ?Y" by (force simp: infer_from_def) also have "\ \ ?X" proof - { fix CAs DA AAs As \ E assume res_e: "ord_resolve_rename CAs DA AAs As \ E" and da_in: "DA \ ?CCC" and cas_sub: "set CAs \ ?CCC" have "E = (THE E. \\. ord_resolve_rename CAs DA AAs As \ E) \ CAs \ CAS \ AAs \ AAS \ As \ AS" (is "?e \ ?cas \ ?aas \ ?as") proof (intro conjI) show ?e using res_e ord_resolve_rename_unique by (blast intro: the_equality[symmetric]) next show ?cas unfolding CAS_def max_ary_def using cas_sub ord_resolve_rename_max_side_prems[OF res_e] da_in fin_cc by (auto simp add: Max_ge_iff) next show ?aas using res_e proof (cases rule: ord_resolve_rename.cases) case (ord_resolve_rename n \ \s) note len_cas = this(1) and len_aas = this(2) and len_as = this(3) and aas_sub = this(4) and as_sub = this(5) and res_e' = this(8) show ?thesis unfolding AAS_def proof (clarify, intro conjI) show "AAs \ lists (mset ` AS)" unfolding AS_def image_def proof clarsimp fix AA assume "AA \ set AAs" then obtain i where i_lt: "i < n" and aa: "AA = AAs ! i" by (metis in_set_conv_nth len_aas) have casi_in: "CAs ! i \ ?CCC" using i_lt len_cas cas_sub nth_mem by blast have pos_aa_sub: "poss AA \# CAs ! i" using aa aas_sub i_lt by blast then have "set_mset AA \ atms_of (CAs ! i)" by (metis atms_of_poss lits_subseteq_imp_atms_subseteq set_mset_mono) also have aa_sub: "\ \ all_AA" unfolding all_AA_def using casi_in by force finally have aa_sub: "set_mset AA \ all_AA" . have "size AA = size (poss AA)" by simp also have "\ \ size (CAs ! i)" by (rule size_mset_mono[OF pos_aa_sub]) also have "\ \ max_ary" unfolding max_ary_def using fin_cc casi_in by auto finally have sz_aa: "size AA \ max_ary" . let ?As' = "sorted_list_of_multiset AA" have "?As' \ lists all_AA" using aa_sub by auto moreover have "length ?As' \ max_ary" using sz_aa by simp moreover have "AA = mset ?As'" by simp ultimately show "\xa. xa \ lists all_AA \ length xa \ max_ary \ AA = mset xa" by blast qed next have "length AAs = length As" unfolding len_aas len_as .. also have "\ \ size DA" using as_sub size_mset_mono by fastforce also have "\ \ max_ary" unfolding max_ary_def using fin_cc da_in by auto finally show "length AAs \ max_ary" . qed qed next show ?as unfolding AS_def proof (clarify, intro conjI) have "set As \ atms_of DA" using res_e[simplified ord_resolve_rename.simps] by (metis atms_of_negs lits_subseteq_imp_atms_subseteq set_mset_mono set_mset_mset) also have "\ \ all_AA" unfolding all_AA_def using da_in by blast finally show "As \ lists all_AA" unfolding lists_eq_set by simp next have "length As \ size DA" using res_e[simplified ord_resolve_rename.simps] ord_resolve_rename_max_side_prems[OF res_e] by auto also have "size DA \ max_ary" unfolding max_ary_def using fin_cc da_in by auto finally show "length As \ max_ary" . qed qed } then show ?thesis by simp fast qed also have "\ \ (\(CAs, DA, AAs, As). ?infer_of CAs DA AAs As) ` ?W" unfolding image_def Bex_cartesian_product by fast finally show ?thesis unfolding inference_system.inferences_between_def ord_FO_\_def mem_Collect_eq by (fast intro: rev_finite_subset[OF finite_imageI[OF fin_w]]) qed lemma ord_FO_resolution_inferences_between_empty_empty: "ord_FO_resolution.inferences_between {} {#} = {}" unfolding ord_FO_resolution.inferences_between_def inference_system.inferences_between_def infer_from_def ord_FO_\_def using ord_resolve_rename_empty_main_prem by auto subsection \Lifting\ text \ The following corresponds to the passage between Lemmas 4.11 and 4.12. \ context fixes M :: "'a clause set" assumes select: "selection S" begin interpretation selection by (rule select) definition S_M :: "'a literal multiset \ 'a literal multiset" where "S_M C = (if C \ grounding_of_clss M then (SOME C'. \D \. D \ M \ C = D \ \ \ C' = S D \ \ \ is_ground_subst \) else S C)" lemma S_M_grounding_of_clss: assumes "C \ grounding_of_clss M" obtains D \ where "D \ M \ C = D \ \ \ S_M C = S D \ \ \ is_ground_subst \" proof (atomize_elim, unfold S_M_def eqTrueI[OF assms] if_True, rule someI_ex) from assms show "\C' D \. D \ M \ C = D \ \ \ C' = S D \ \ \ is_ground_subst \" by (auto simp: grounding_of_clss_def grounding_of_cls_def) qed lemma S_M_not_grounding_of_clss: "C \ grounding_of_clss M \ S_M C = S C" unfolding S_M_def by simp lemma S_M_selects_subseteq: "S_M C \# C" by (metis S_M_grounding_of_clss S_M_not_grounding_of_clss S_selects_subseteq subst_cls_mono_mset) lemma S_M_selects_neg_lits: "L \# S_M C \ is_neg L" by (metis Melem_subst_cls S_M_grounding_of_clss S_M_not_grounding_of_clss S_selects_neg_lits subst_lit_is_neg) end end text \ The following corresponds to Lemma 4.12: \ lemma ground_resolvent_subset: assumes gr_cas: "is_ground_cls_list CAs" and gr_da: "is_ground_cls DA" and res_e: "ord_resolve S CAs DA AAs As \ E" shows "E \# \\<^sub># (mset CAs) + DA" using res_e proof (cases rule: ord_resolve.cases) case (ord_resolve n Cs D) note da = this(1) and e = this(2) and cas_len = this(3) and cs_len = this(4) and aas_len = this(5) and as_len = this(6) and cas = this(8) and mgu = this(10) then have cs_sub_cas: "\\<^sub># (mset Cs) \# \\<^sub># (mset CAs)" using subseteq_list_Union_mset cas_len cs_len by force then have cs_sub_cas: "\\<^sub># (mset Cs) \# \\<^sub># (mset CAs)" using subseteq_list_Union_mset cas_len cs_len by force then have gr_cs: "is_ground_cls_list Cs" using gr_cas by simp have d_sub_da: "D \# DA" by (simp add: da) then have gr_d: "is_ground_cls D" using gr_da is_ground_cls_mono by auto have "is_ground_cls (\\<^sub># (mset Cs) + D)" using gr_cs gr_d by auto with e have "E = \\<^sub># (mset Cs) + D" by auto then show ?thesis using cs_sub_cas d_sub_da by (auto simp: subset_mset.add_mono) qed lemma ord_resolve_obtain_clauses: assumes res_e: "ord_resolve (S_M S M) CAs DA AAs As \ E" and select: "selection S" and grounding: "{DA} \ set CAs \ grounding_of_clss M" and n: "length CAs = n" and d: "DA = D + negs (mset As)" and c: "(\i < n. CAs ! i = Cs ! i + poss (AAs ! i))" "length Cs = n" "length AAs = n" obtains DA0 \0 CAs0 \s0 As0 AAs0 D0 Cs0 where "length CAs0 = n" "length \s0 = n" "DA0 \ M" "DA0 \ \0 = DA" "S DA0 \ \0 = S_M S M DA" "\CA0 \ set CAs0. CA0 \ M" "CAs0 \\cl \s0 = CAs" "map S CAs0 \\cl \s0 = map (S_M S M) CAs" "is_ground_subst \0" "is_ground_subst_list \s0" "As0 \al \0 = As" "AAs0 \\aml \s0 = AAs" "length As0 = n" "D0 \ \0 = D" "DA0 = D0 + (negs (mset As0))" "S_M S M (D + negs (mset As)) \ {#} \ negs (mset As0) = S DA0" "length Cs0 = n" "Cs0 \\cl \s0 = Cs" "\i < n. CAs0 ! i = Cs0 ! i + poss (AAs0 ! i)" "length AAs0 = n" using res_e proof (cases rule: ord_resolve.cases) case (ord_resolve n_twin Cs_twins D_twin) note da = this(1) and e = this(2) and cas = this(8) and mgu = this(10) and eligible = this(11) from ord_resolve have "n_twin = n" "D_twin = D" using n d by auto moreover have "Cs_twins = Cs" using c cas n calculation(1) \length Cs_twins = n_twin\ by (auto simp add: nth_equalityI) ultimately have nz: "n \ 0" and cs_len: "length Cs = n" and aas_len: "length AAs = n" and as_len: "length As = n" and da: "DA = D + negs (mset As)" and eligible: "eligible (S_M S M) \ As (D + negs (mset As))" and cas: "\in \ 0\ \length CAs = n\ \length Cs = n\ \length AAs = n\ \length As = n\ interpret S: selection S by (rule select) \ \Obtain FO side premises\ have "\CA \ set CAs. \CA0 \c0. CA0 \ M \ CA0 \ \c0 = CA \ S CA0 \ \c0 = S_M S M CA \ is_ground_subst \c0" using grounding S_M_grounding_of_clss select by (metis (no_types) le_supE subset_iff) then have "\i < n. \CA0 \c0. CA0 \ M \ CA0 \ \c0 = (CAs ! i) \ S CA0 \ \c0 = S_M S M (CAs ! i) \ is_ground_subst \c0" using n by force then obtain \s0f CAs0f where f_p: "\i < n. CAs0f i \ M" "\i < n. (CAs0f i) \ (\s0f i) = (CAs ! i)" "\i < n. S (CAs0f i) \ (\s0f i) = S_M S M (CAs ! i)" "\i < n. is_ground_subst (\s0f i)" using n by (metis (no_types)) define \s0 where "\s0 = map \s0f [0 ..s0 = n" "length CAs0 = n" unfolding \s0_def CAs0_def by auto note n = \length \s0 = n\ \length CAs0 = n\ n \ \The properties we need of the FO side premises\ have CAs0_in_M: "\CA0 \ set CAs0. CA0 \ M" unfolding CAs0_def using f_p(1) by auto have CAs0_to_CAs: "CAs0 \\cl \s0 = CAs" unfolding CAs0_def \s0_def using f_p(2) by (auto simp: n intro: nth_equalityI) have SCAs0_to_SMCAs: "(map S CAs0) \\cl \s0 = map (S_M S M) CAs" unfolding CAs0_def \s0_def using f_p(3) n by (force intro: nth_equalityI) have sub_ground: "\\c0 \ set \s0. is_ground_subst \c0" unfolding \s0_def using f_p n by force then have "is_ground_subst_list \s0" using n unfolding is_ground_subst_list_def by auto \ \Split side premises CAs0 into Cs0 and AAs0\ obtain AAs0 Cs0 where AAs0_Cs0_p: "AAs0 \\aml \s0 = AAs" "length Cs0 = n" "Cs0 \\cl \s0 = Cs" "\i < n. CAs0 ! i = Cs0 ! i + poss (AAs0 ! i)" "length AAs0 = n" proof - have "\i < n. \AA0. AA0 \am \s0 ! i = AAs ! i \ poss AA0 \# CAs0 ! i" proof (rule, rule) fix i assume "i < n" have "CAs0 ! i \ \s0 ! i = CAs ! i" using \i < n\ \CAs0 \\cl \s0 = CAs\ n by force moreover have "poss (AAs ! i) \# CAs !i" using \i < n\ cas by auto ultimately obtain poss_AA0 where nn: "poss_AA0 \ \s0 ! i = poss (AAs ! i) \ poss_AA0 \# CAs0 ! i" using cas image_mset_of_subset unfolding subst_cls_def by metis then have l: "\L \# poss_AA0. is_pos L" unfolding subst_cls_def by (metis Melem_subst_cls imageE literal.disc(1) literal.map_disc_iff set_image_mset subst_cls_def subst_lit_def) define AA0 where "AA0 = image_mset atm_of poss_AA0" have na: "poss AA0 = poss_AA0" using l unfolding AA0_def by auto then have "AA0 \am \s0 ! i = AAs ! i" using nn by (metis (mono_tags) literal.inject(1) multiset.inj_map_strong subst_cls_poss) moreover have "poss AA0 \# CAs0 ! i" using na nn by auto ultimately show "\AA0. AA0 \am \s0 ! i = AAs ! i \ poss AA0 \# CAs0 ! i" by blast qed then obtain AAs0f where AAs0f_p: "\i < n. AAs0f i \am \s0 ! i = AAs ! i \ (poss (AAs0f i)) \# CAs0 ! i" by metis define AAs0 where "AAs0 = map AAs0f [0 ..length AAs0 = n\ from AAs0_def have "\i < n. AAs0 ! i \am \s0 ! i = AAs ! i" using AAs0f_p by auto then have AAs0_AAs: "AAs0 \\aml \s0 = AAs" using n by (auto intro: nth_equalityI) from AAs0_def have AAs0_in_CAs0: "\i < n. poss (AAs0 ! i) \# CAs0 ! i" using AAs0f_p by auto define Cs0 where "Cs0 = map2 (-) CAs0 (map poss AAs0)" have "length Cs0 = n" using Cs0_def n by auto note n = n \length Cs0 = n\ have "\i < n. CAs0 ! i = Cs0 ! i + poss (AAs0 ! i)" using AAs0_in_CAs0 Cs0_def n by auto then have "Cs0 \\cl \s0 = Cs" using \CAs0 \\cl \s0 = CAs\ AAs0_AAs cas n by (auto intro: nth_equalityI) show ?thesis using that \AAs0 \\aml \s0 = AAs\ \Cs0 \\cl \s0 = Cs\ \\i < n. CAs0 ! i = Cs0 ! i + poss (AAs0 ! i)\ \length AAs0 = n\ \length Cs0 = n\ by blast qed \ \Obtain FO main premise\ have "\DA0 \0. DA0 \ M \ DA = DA0 \ \0 \ S DA0 \ \0 = S_M S M DA \ is_ground_subst \0" using grounding S_M_grounding_of_clss select by (metis le_supE singletonI subsetCE) then obtain DA0 \0 where DA0_\0_p: "DA0 \ M \ DA = DA0 \ \0 \ S DA0 \ \0 = S_M S M DA \ is_ground_subst \0" by auto \ \The properties we need of the FO main premise\ have DA0_in_M: "DA0 \ M" using DA0_\0_p by auto have DA0_to_DA: "DA0 \ \0 = DA" using DA0_\0_p by auto have SDA0_to_SMDA: "S DA0 \ \0 = S_M S M DA" using DA0_\0_p by auto have "is_ground_subst \0" using DA0_\0_p by auto \ \Split main premise DA0 into D0 and As0\ obtain D0 As0 where D0As0_p: "As0 \al \0 = As" "length As0 = n" "D0 \ \0 = D" "DA0 = D0 + (negs (mset As0))" "S_M S M (D + negs (mset As)) \ {#} \ negs (mset As0) = S DA0" proof - { assume a: "S_M S M (D + negs (mset As)) = {#} \ length As = (Suc 0) \ maximal_wrt (As ! 0 \a \) ((D + negs (mset As)) \ \)" then have as: "mset As = {#As ! 0#}" by (auto intro: nth_equalityI) then have "negs (mset As) = {#Neg (As ! 0)#}" by (simp add: \mset As = {#As ! 0#}\) then have "DA = D + {#Neg (As ! 0)#}" using da by auto then obtain L where "L \# DA0 \ L \l \0 = Neg (As ! 0)" using DA0_to_DA by (metis Melem_subst_cls mset_subset_eq_add_right single_subset_iff) then have "Neg (atm_of L) \# DA0 \ Neg (atm_of L) \l \0 = Neg (As ! 0)" by (metis Neg_atm_of_iff literal.sel(2) subst_lit_is_pos) then have "[atm_of L] \al \0 = As \ negs (mset [atm_of L]) \# DA0" using as subst_lit_def by auto then have "\As0. As0 \al \0 = As \ negs (mset As0) \# DA0 \ (S_M S M (D + negs (mset As)) \ {#} \ negs (mset As0) = S DA0)" using a by blast } moreover { assume "S_M S M (D + negs (mset As)) = negs (mset As)" then have "negs (mset As) = S DA0 \ \0" using da \S DA0 \ \0 = S_M S M DA\ by auto then have "\As0. negs (mset As0) = S DA0 \ As0 \al \0 = As" using instance_list[of As "S DA0" \0] S.S_selects_neg_lits by auto then have "\As0. As0 \al \0 = As \ negs (mset As0) \# DA0 \ (S_M S M (D + negs (mset As)) \ {#} \ negs (mset As0) = S DA0)" using S.S_selects_subseteq by auto } ultimately have "\As0. As0 \al \0 = As \ (negs (mset As0)) \# DA0 \ (S_M S M (D + negs (mset As)) \ {#} \ negs (mset As0) = S DA0)" using eligible unfolding eligible.simps by auto then obtain As0 where As0_p: "As0 \al \0 = As \ negs (mset As0) \# DA0 \ (S_M S M (D + negs (mset As)) \ {#} \ negs (mset As0) = S DA0)" by blast then have "length As0 = n" using as_len by auto note n = n this have "As0 \al \0 = As" using As0_p by auto define D0 where "D0 = DA0 - negs (mset As0)" then have "DA0 = D0 + negs (mset As0)" using As0_p by auto then have "D0 \ \0 = D" using DA0_to_DA da As0_p by auto have "S_M S M (D + negs (mset As)) \ {#} \ negs (mset As0) = S DA0" using As0_p by blast then show ?thesis using that \As0 \al \0 = As\ \D0 \ \0= D\ \DA0 = D0 + (negs (mset As0))\ \length As0 = n\ by metis qed show ?thesis using that[OF n(2,1) DA0_in_M DA0_to_DA SDA0_to_SMDA CAs0_in_M CAs0_to_CAs SCAs0_to_SMCAs \is_ground_subst \0\ \is_ground_subst_list \s0\ \As0 \al \0 = As\ \AAs0 \\aml \s0 = AAs\ \length As0 = n\ \D0 \ \0 = D\ \DA0 = D0 + (negs (mset As0))\ \S_M S M (D + negs (mset As)) \ {#} \ negs (mset As0) = S DA0\ \length Cs0 = n\ \Cs0 \\cl \s0 = Cs\ \\i < n. CAs0 ! i = Cs0 ! i + poss (AAs0 ! i)\ \length AAs0 = n\] by auto qed lemma ord_resolve_rename_lifting: assumes sel_stable: "\\ C. is_renaming \ \ S (C \ \) = S C \ \" and res_e: "ord_resolve (S_M S M) CAs DA AAs As \ E" and select: "selection S" and grounding: "{DA} \ set CAs \ grounding_of_clss M" obtains \s \ \2 CAs0 DA0 AAs0 As0 E0 \ where "is_ground_subst \" "is_ground_subst_list \s" "is_ground_subst \2" "ord_resolve_rename S CAs0 DA0 AAs0 As0 \ E0" "CAs0 \\cl \s = CAs" "DA0 \ \ = DA" "E0 \ \2 = E" "{DA0} \ set CAs0 \ M" "length CAs0 = length CAs" "length \s = length CAs" using res_e proof (cases rule: ord_resolve.cases) case (ord_resolve n Cs D) note da = this(1) and e = this(2) and cas_len = this(3) and cs_len = this(4) and aas_len = this(5) and as_len = this(6) and nz = this(7) and cas = this(8) and aas_not_empt = this(9) and mgu = this(10) and eligible = this(11) and str_max = this(12) and sel_empt = this(13) have sel_ren_list_inv: "\\s Cs. length \s = length Cs \ is_renaming_list \s \ map S (Cs \\cl \s) = map S Cs \\cl \s" using sel_stable unfolding is_renaming_list_def by (auto intro: nth_equalityI) note n = \n \ 0\ \length CAs = n\ \length Cs = n\ \length AAs = n\ \length As = n\ interpret S: selection S by (rule select) obtain DA0 \0 CAs0 \s0 As0 AAs0 D0 Cs0 where as0: "length CAs0 = n" "length \s0 = n" "DA0 \ M" "DA0 \ \0 = DA" "S DA0 \ \0 = S_M S M DA" "\CA0 \ set CAs0. CA0 \ M" "CAs0 \\cl \s0 = CAs" "map S CAs0 \\cl \s0 = map (S_M S M) CAs" "is_ground_subst \0" "is_ground_subst_list \s0" "As0 \al \0 = As" "AAs0 \\aml \s0 = AAs" "length As0 = n" "D0 \ \0 = D" "DA0 = D0 + (negs (mset As0))" "S_M S M (D + negs (mset As)) \ {#} \ negs (mset As0) = S DA0" "length Cs0 = n" "Cs0 \\cl \s0 = Cs" "\i < n. CAs0 ! i = Cs0 ! i + poss (AAs0 ! i)" "length AAs0 = n" using ord_resolve_obtain_clauses[of S M CAs DA, OF res_e select grounding n(2) \DA = D + negs (mset As)\ \\i \length Cs = n\ \length AAs = n\, of thesis] by blast note n = \length CAs0 = n\ \length \s0 = n\ \length As0 = n\ \length AAs0 = n\ \length Cs0 = n\ n have "length (renamings_apart (DA0 # CAs0)) = Suc n" using n renamings_apart_length by auto note n = this n define \ where "\ = hd (renamings_apart (DA0 # CAs0))" define \s where "\s = tl (renamings_apart (DA0 # CAs0))" define DA0' where "DA0' = DA0 \ \" define D0' where "D0' = D0 \ \" define As0' where "As0' = As0 \al \" define CAs0' where "CAs0' = CAs0 \\cl \s" define Cs0' where "Cs0' = Cs0 \\cl \s" define AAs0' where "AAs0' = AAs0 \\aml \s" define \0' where "\0' = inv_renaming \ \ \0" define \s0' where "\s0' = map inv_renaming \s \s \s0" have renames_DA0: "is_renaming \" using renamings_apart_length renamings_apart_renaming unfolding \_def by (metis length_greater_0_conv list.exhaust_sel list.set_intros(1) list.simps(3)) have renames_CAs0: "is_renaming_list \s" using renamings_apart_length renamings_apart_renaming unfolding \s_def by (metis is_renaming_list_def length_greater_0_conv list.set_sel(2) list.simps(3)) have "length \s = n" unfolding \s_def using n by auto note n = n \length \s = n\ have "length As0' = n" unfolding As0'_def using n by auto have "length CAs0' = n" using as0(1) n unfolding CAs0'_def by auto have "length Cs0' = n" unfolding Cs0'_def using n by auto have "length AAs0' = n" unfolding AAs0'_def using n by auto have "length \s0' = n" using as0(2) n unfolding \s0'_def by auto note n = \length CAs0' = n\ \length \s0' = n\ \length As0' = n\ \length AAs0' = n\ \length Cs0' = n\ n have DA0'_DA: "DA0' \ \0' = DA" using as0(4) unfolding \0'_def DA0'_def using renames_DA0 by simp have D0'_D: "D0' \ \0' = D" using as0(14) unfolding \0'_def D0'_def using renames_DA0 by simp have As0'_As: "As0' \al \0' = As" using as0(11) unfolding \0'_def As0'_def using renames_DA0 by auto have "S DA0' \ \0' = S_M S M DA" using as0(5) unfolding \0'_def DA0'_def using renames_DA0 sel_stable by auto have CAs0'_CAs: "CAs0' \\cl \s0' = CAs" using as0(7) unfolding CAs0'_def \s0'_def using renames_CAs0 n by auto have Cs0'_Cs: "Cs0' \\cl \s0' = Cs" using as0(18) unfolding Cs0'_def \s0'_def using renames_CAs0 n by auto have AAs0'_AAs: "AAs0' \\aml \s0' = AAs" using as0(12) unfolding \s0'_def AAs0'_def using renames_CAs0 using n by auto have "map S CAs0' \\cl \s0' = map (S_M S M) CAs" unfolding CAs0'_def \s0'_def using as0(8) n renames_CAs0 sel_ren_list_inv by auto have DA0'_split: "DA0' = D0' + negs (mset As0')" using as0(15) DA0'_def D0'_def As0'_def by auto then have D0'_subset_DA0': "D0' \# DA0'" by auto from DA0'_split have negs_As0'_subset_DA0': "negs (mset As0') \# DA0'" by auto have CAs0'_split: "\ii# CAs0' ! i" by auto from CAs0'_split have poss_AAs0'_subset_CAs0': "\i# CAs0' ! i" by auto then have AAs0'_in_atms_of_CAs0': "\i < n. \A\#AAs0' ! i. A \ atms_of (CAs0' ! i)" by (auto simp add: atm_iff_pos_or_neg_lit) have as0': "S_M S M (D + negs (mset As)) \ {#} \ negs (mset As0') = S DA0'" proof - assume a: "S_M S M (D + negs (mset As)) \ {#}" then have "negs (mset As0) \ \ = S DA0 \ \" using as0(16) unfolding \_def by metis then show "negs (mset As0') = S DA0'" using As0'_def DA0'_def using sel_stable[of \ DA0] renames_DA0 by auto qed have vd: "var_disjoint (DA0' # CAs0')" unfolding DA0'_def CAs0'_def using renamings_apart_var_disjoint unfolding \_def \s_def by (metis length_greater_0_conv list.exhaust_sel n(6) substitution.subst_cls_lists_Cons substitution_axioms zero_less_Suc) \ \Introduce ground substitution\ from vd DA0'_DA CAs0'_CAs have "\\. \i < Suc n. \S. S \# (DA0' # CAs0') ! i \ S \ (\0'#\s0') ! i = S \ \" unfolding var_disjoint_def using n by auto then obtain \ where \_p: "\i < Suc n. \S. S \# (DA0' # CAs0') ! i \ S \ (\0'#\s0') ! i = S \ \" by auto have \_p_lit: "\i < Suc n. \L. L \# (DA0' # CAs0') ! i \ L \l (\0'#\s0') ! i = L \l \" proof (rule, rule, rule, rule) fix i :: "nat" and L :: "'a literal" assume a: "i < Suc n" "L \# (DA0' # CAs0') ! i" then have "\S. S \# (DA0' # CAs0') ! i \ S \ (\0' # \s0') ! i = S \ \" using \_p by auto then have "{# L #} \ (\0' # \s0') ! i = {# L #} \ \" using a by (meson single_subset_iff) then show "L \l (\0' # \s0') ! i = L \l \" by auto qed have \_p_atm: "\i < Suc n. \A. A \ atms_of ((DA0' # CAs0') ! i) \ A \a (\0'#\s0') ! i = A \a \" proof (rule, rule, rule, rule) fix i :: "nat" and A :: "'a" assume a: "i < Suc n" "A \ atms_of ((DA0' # CAs0') ! i)" then obtain L where L_p: "atm_of L = A \ L \# (DA0' # CAs0') ! i" unfolding atms_of_def by auto then have "L \l (\0'#\s0') ! i = L \l \" using \_p_lit a by auto then show "A \a (\0' # \s0') ! i = A \a \" using L_p unfolding subst_lit_def by (cases L) auto qed have DA0'_DA: "DA0' \ \ = DA" using DA0'_DA \_p by auto have "D0' \ \ = D" using \_p D0'_D n D0'_subset_DA0' by auto have "As0' \al \ = As" proof (rule nth_equalityI) show "length (As0' \al \) = length As" using n by auto next fix i show "ial \) \ (As0' \al \) ! i = As ! i" proof - assume a: "i < length (As0' \al \)" have A_eq: "\A. A \ atms_of DA0' \ A \a \0' = A \a \" using \_p_atm n by force have "As0' ! i \ atms_of DA0'" using negs_As0'_subset_DA0' unfolding atms_of_def using a n by force then have "As0' ! i \a \0' = As0' ! i \a \" using A_eq by simp then show "(As0' \al \) ! i = As ! i" using As0'_As \length As0' = n\ a by auto qed qed interpret selection by (rule select) have "S DA0' \ \ = S_M S M DA" using \S DA0' \ \0' = S_M S M DA\ \_p S.S_selects_subseteq by auto from \_p have \_p_CAs0': "\i < n. (CAs0' ! i) \ (\s0' ! i) = (CAs0'! i) \ \" using n by auto then have "CAs0' \\cl \s0' = CAs0' \cl \" using n by (auto intro: nth_equalityI) then have CAs0'_\_fo_CAs: "CAs0' \cl \ = CAs" using CAs0'_CAs \_p n by auto from \_p have "\i < n. S (CAs0' ! i) \ \s0' ! i = S (CAs0' ! i) \ \" using S.S_selects_subseteq n by auto then have "map S CAs0' \\cl \s0' = map S CAs0' \cl \" using n by (auto intro: nth_equalityI) then have SCAs0'_\_fo_SMCAs: "map S CAs0' \cl \ = map (S_M S M) CAs" using \map S CAs0' \\cl \s0' = map (S_M S M) CAs\ by auto have "Cs0' \cl \ = Cs" proof (rule nth_equalityI) show "length (Cs0' \cl \) = length Cs" using n by auto next fix i show "icl \) \ (Cs0' \cl \) ! i = Cs ! i" proof - assume "i < length (Cs0' \cl \)" then have a: "i < n" using n by force have "(Cs0' \\cl \s0') ! i = Cs ! i" using Cs0'_Cs a n by force moreover have \_p_CAs0': "\S. S \# CAs0' ! i \ S \ \s0' ! i = S \ \" using \_p a by force have "Cs0' ! i \ \s0' ! i = (Cs0' \cl \) ! i" using \_p_CAs0' \\i# CAs0' ! i\ a n by force then have "(Cs0' \\cl \s0') ! i = (Cs0' \cl \) ! i " using a n by force ultimately show "(Cs0' \cl \) ! i = Cs ! i" by auto qed qed have AAs0'_AAs: "AAs0' \aml \ = AAs" proof (rule nth_equalityI) show "length (AAs0' \aml \) = length AAs" using n by auto next fix i show "iaml \) \ (AAs0' \aml \) ! i = AAs ! i" proof - assume a: "i < length (AAs0' \aml \)" then have "i < n" using n by force then have "\A. A \ atms_of ((DA0' # CAs0') ! Suc i) \ A \a (\0' # \s0') ! Suc i = A \a \" using \_p_atm n by force then have A_eq: "\A. A \ atms_of (CAs0' ! i) \ A \a \s0' ! i = A \a \" by auto have AAs_CAs0': "\A \# AAs0' ! i. A \ atms_of (CAs0' ! i)" using AAs0'_in_atms_of_CAs0' unfolding atms_of_def using a n by force then have "AAs0' ! i \am \s0' ! i = AAs0' ! i \am \" unfolding subst_atm_mset_def using A_eq unfolding subst_atm_mset_def by auto then show "(AAs0' \aml \) ! i = AAs ! i" using AAs0'_AAs \length AAs0' = n\ \length \s0' = n\ a by auto qed qed \ \Obtain MGU and substitution\ obtain \ \ where \\: "Some \ = mgu (set_mset ` set (map2 add_mset As0' AAs0'))" "\ \ \ = \ \ \" proof - have uu: "is_unifiers \ (set_mset ` set (map2 add_mset (As0' \al \) (AAs0' \aml \)))" using mgu mgu_sound is_mgu_def unfolding \AAs0' \aml \ = AAs\ using \As0' \al \ = As\ by auto have \\uni: "is_unifiers (\ \ \) (set_mset ` set (map2 add_mset As0' AAs0'))" proof - have "set_mset ` set (map2 add_mset As0' AAs0' \aml \) = set_mset ` set (map2 add_mset As0' AAs0') \ass \" unfolding subst_atmss_def subst_atm_mset_list_def using subst_atm_mset_def subst_atms_def by (simp add: image_image subst_atm_mset_def subst_atms_def) then have "is_unifiers \ (set_mset ` set (map2 add_mset As0' AAs0') \ass \)" using uu by (auto simp: n map2_add_mset_map) then show ?thesis using is_unifiers_comp by auto qed then obtain \ where \_p: "Some \ = mgu (set_mset ` set (map2 add_mset As0' AAs0'))" using mgu_complete by (metis (mono_tags, opaque_lifting) List.finite_set finite_imageI finite_set_mset image_iff) moreover then obtain \ where \_p: "\ \ \ = \ \ \" by (metis (mono_tags, opaque_lifting) finite_set \\uni finite_imageI finite_set_mset image_iff mgu_sound set_mset_mset substitution_ops.is_mgu_def) (* should be simpler *) ultimately show thesis using that by auto qed \ \Lifting eligibility\ have eligible0': "eligible S \ As0' (D0' + negs (mset As0'))" proof - have "S_M S M (D + negs (mset As)) = negs (mset As) \ S_M S M (D + negs (mset As)) = {#} \ length As = 1 \ maximal_wrt (As ! 0 \a \) ((D + negs (mset As)) \ \)" using eligible unfolding eligible.simps by auto then show ?thesis proof assume "S_M S M (D + negs (mset As)) = negs (mset As)" then have "S_M S M (D + negs (mset As)) \ {#}" using n by force then have "S (D0' + negs (mset As0')) = negs (mset As0')" using as0' DA0'_split by auto then show ?thesis unfolding eligible.simps[simplified] by auto next assume asm: "S_M S M (D + negs (mset As)) = {#} \ length As = 1 \ maximal_wrt (As ! 0 \a \) ((D + negs (mset As)) \ \)" then have "S (D0' + negs (mset As0')) = {#}" using \D0' \ \ = D\[symmetric] \As0' \al \ = As\[symmetric] \S (DA0') \ \ = S_M S M (DA)\ da DA0'_split subst_cls_empty_iff by metis moreover from asm have l: "length As0' = 1" using \As0' \al \ = As\ by auto moreover from asm have "maximal_wrt (As0' ! 0 \a (\ \ \)) ((D0' + negs (mset As0')) \ (\ \ \))" using \As0' \al \ = As\ \D0' \ \ = D\ using l \\ by auto then have "maximal_wrt (As0' ! 0 \a \ \a \) ((D0' + negs (mset As0')) \ \ \ \)" by auto then have "maximal_wrt (As0' ! 0 \a \) ((D0' + negs (mset As0')) \ \)" using maximal_wrt_subst by blast ultimately show ?thesis unfolding eligible.simps[simplified] by auto qed qed \ \Lifting maximality\ have maximality: "\i < n. strictly_maximal_wrt (As0' ! i \a \) (Cs0' ! i \ \)" (* Reformulate in list notation? *) proof - from str_max have "\i < n. strictly_maximal_wrt ((As0' \al \) ! i \a \) ((Cs0' \cl \) ! i \ \)" using \As0' \al \ = As\ \Cs0' \cl \ = Cs\ by simp then have "\i < n. strictly_maximal_wrt (As0' ! i \a (\ \ \)) (Cs0' ! i \ (\ \ \))" using n \\ by simp then have "\i < n. strictly_maximal_wrt (As0' ! i \a \ \a \) (Cs0' ! i \ \ \ \)" by auto then show "\i < n. strictly_maximal_wrt (As0' ! i \a \) (Cs0' ! i \ \)" using strictly_maximal_wrt_subst \\ by blast qed \ \Lifting nothing being selected\ have nothing_selected: "\i < n. S (CAs0' ! i) = {#}" proof - have "\i < n. (map S CAs0' \cl \) ! i = map (S_M S M) CAs ! i" by (simp add: \map S CAs0' \cl \ = map (S_M S M) CAs\) then have "\i < n. S (CAs0' ! i) \ \ = S_M S M (CAs ! i)" using n by auto then have "\i < n. S (CAs0' ! i) \ \ = {#}" using sel_empt \\i < n. S (CAs0' ! i) \ \ = S_M S M (CAs ! i)\ by auto then show "\i < n. S (CAs0' ! i) = {#}" using subst_cls_empty_iff by blast qed \ \Lifting AAs0's non-emptiness\ have "\i < n. AAs0' ! i \ {#}" using n aas_not_empt \AAs0' \aml \ = AAs\ by auto \ \Resolve the lifted clauses\ define E0' where "E0' = ((\\<^sub># (mset Cs0')) + D0') \ \" have res_e0': "ord_resolve S CAs0' DA0' AAs0' As0' \ E0'" using ord_resolve.intros[of CAs0' n Cs0' AAs0' As0' \ S D0', OF _ _ _ _ _ _ \\i < n. AAs0' ! i \ {#}\ \\(1) eligible0' \\i < n. strictly_maximal_wrt (As0' ! i \a \) (Cs0' ! i \ \)\ \\i < n. S (CAs0' ! i) = {#}\] unfolding E0'_def using DA0'_split n \\i by blast \ \Prove resolvent instantiates to ground resolvent\ have e0'\e: "E0' \ \ = E" proof - have "E0' \ \ = ((\\<^sub># (mset Cs0')) + D0') \ (\ \ \)" unfolding E0'_def by auto also have "\ = (\\<^sub># (mset Cs0') + D0') \ (\ \ \)" using \\ by auto also have "\ = (\\<^sub># (mset Cs) + D) \ \" using \Cs0' \cl \ = Cs\ \D0' \ \ = D\ by auto also have "\ = E" using e by auto finally show e0'\e: "E0' \ \ = E" . qed \ \Replace @{term \} with a true ground substitution\ obtain \2 where ground_\2: "is_ground_subst \2" "E0' \ \2 = E" proof - have "is_ground_cls_list CAs" "is_ground_cls DA" using grounding grounding_ground unfolding is_ground_cls_list_def by auto then have "is_ground_cls E" using res_e ground_resolvent_subset by (force intro: is_ground_cls_mono) then show thesis using that e0'\e make_ground_subst by auto qed have \length CAs0 = length CAs\ using n by simp have \length \s0 = length CAs\ using n by simp \ \Wrap up the proof\ have "ord_resolve S (CAs0 \\cl \s) (DA0 \ \) (AAs0 \\aml \s) (As0 \al \) \ E0'" using res_e0' As0'_def \_def AAs0'_def \s_def DA0'_def \_def CAs0'_def \s_def by simp moreover have "\i# CAs0 ! i" using as0(19) by auto moreover have "negs (mset As0) \# DA0" using local.as0(15) by auto ultimately have "ord_resolve_rename S CAs0 DA0 AAs0 As0 \ E0'" using ord_resolve_rename[of CAs0 n AAs0 As0 DA0 \ \s S \ E0'] \_def \s_def n by auto then show thesis using that[of \0 \s0 \2 CAs0 DA0] \is_ground_subst \0\ \is_ground_subst_list \s0\ \is_ground_subst \2\ \CAs0 \\cl \s0 = CAs\ \DA0 \ \0 = DA\ \E0' \ \2 = E\ \DA0 \ M\ \\CA \ set CAs0. CA \ M\ \length CAs0 = length CAs\ \length \s0 = length CAs\ by blast qed lemma ground_ord_resolve_ground: assumes select: "selection S" and CAs_p: "ground_resolution_with_selection.ord_resolve S CAs DA AAs As E" and ground_cas: "is_ground_cls_list CAs" and ground_da: "is_ground_cls DA" shows "is_ground_cls E" proof - have a1: "atms_of E \ (\CA \ set CAs. atms_of CA) \ atms_of DA" using ground_resolution_with_selection.ord_resolve_atms_of_concl_subset[OF _ CAs_p] ground_resolution_with_selection.intro[OF select] by blast { fix L :: "'a literal" assume "L \# E" then have "atm_of L \ atms_of E" by (meson atm_of_lit_in_atms_of) then have "is_ground_atm (atm_of L)" using a1 ground_cas ground_da is_ground_cls_imp_is_ground_atm is_ground_cls_list_def by auto } then show ?thesis unfolding is_ground_cls_def is_ground_lit_def by simp qed lemma ground_ord_resolve_imp_ord_resolve: assumes ground_da: \is_ground_cls DA\ and ground_cas: \is_ground_cls_list CAs\ and gr: "ground_resolution_with_selection S_G" and gr_res: \ground_resolution_with_selection.ord_resolve S_G CAs DA AAs As E\ shows \\\. ord_resolve S_G CAs DA AAs As \ E\ proof (cases rule: ground_resolution_with_selection.ord_resolve.cases[OF gr gr_res]) case (1 CAs n Cs AAs As D) note cas = this(1) and da = this(2) and aas = this(3) and as = this(4) and e = this(5) and cas_len = this(6) and cs_len = this(7) and aas_len = this(8) and as_len = this(9) and nz = this(10) and casi = this(11) and aas_not_empt = this(12) and as_aas = this(13) and eligibility = this(14) and str_max = this(15) and sel_empt = this(16) have len_aas_len_as: "length AAs = length As" using aas_len as_len by auto from as_aas have "\i < n. \A \# add_mset (As ! i) (AAs ! i). A = As ! i" by simp then have "\i < n. card (set_mset (add_mset (As ! i) (AAs ! i))) \ Suc 0" using all_the_same by metis then have "\i < length AAs. card (set_mset (add_mset (As ! i) (AAs ! i))) \ Suc 0" using aas_len by auto then have "\AA \ set (map2 add_mset As AAs). card (set_mset AA) \ Suc 0" using set_map2_ex[of AAs As add_mset, OF len_aas_len_as] by auto then have "is_unifiers id_subst (set_mset ` set (map2 add_mset As AAs))" unfolding is_unifiers_def is_unifier_def by auto moreover have "finite (set_mset ` set (map2 add_mset As AAs))" by auto moreover have "\AA \ set_mset ` set (map2 add_mset As AAs). finite AA" by auto ultimately obtain \ where \_p: "Some \ = mgu (set_mset ` set (map2 add_mset As AAs))" using mgu_complete by metis have ground_elig: "ground_resolution_with_selection.eligible S_G As (D + negs (mset As))" using eligibility by simp have ground_cs: "\i < n. is_ground_cls (Cs ! i)" using cas cas_len cs_len casi ground_cas nth_mem unfolding is_ground_cls_list_def by force have ground_set_as: "is_ground_atms (set As)" using da ground_da by (metis atms_of_negs is_ground_cls_is_ground_atms_atms_of is_ground_cls_union set_mset_mset) then have ground_mset_as: "is_ground_atm_mset (mset As)" unfolding is_ground_atm_mset_def is_ground_atms_def by auto have ground_as: "is_ground_atm_list As" using ground_set_as is_ground_atm_list_def is_ground_atms_def by auto have ground_d: "is_ground_cls D" using ground_da da by simp from as_len nz have atms: "atms_of D \ set As \ {}" "finite (atms_of D \ set As)" by auto then have "Max (atms_of D \ set As) \ atms_of D \ set As" using Max_in by metis then have is_ground_Max: "is_ground_atm (Max (atms_of D \ set As))" using ground_d ground_mset_as is_ground_cls_imp_is_ground_atm unfolding is_ground_atm_mset_def by auto have "maximal_wrt (Max (atms_of D \ set As)) (D + negs (mset As))" unfolding maximal_wrt_def by clarsimp (metis atms Max_less_iff UnCI ground_d ground_set_as infinite_growing is_ground_Max is_ground_atms_def is_ground_cls_imp_is_ground_atm less_atm_ground) moreover have "Max (atms_of D \ set As) \a \ = Max (atms_of D \ set As)" and "D \ \ + negs (mset As \am \) = D + negs (mset As)" using ground_elig is_ground_Max ground_mset_as ground_d by auto ultimately have fo_elig: "eligible S_G \ As (D + negs (mset As))" using ground_elig unfolding ground_resolution_with_selection.eligible.simps[OF gr] ground_resolution_with_selection.maximal_wrt_def[OF gr] eligible.simps by auto have "\i < n. strictly_maximal_wrt (As ! i) (Cs ! i)" using str_max[unfolded ground_resolution_with_selection.strictly_maximal_wrt_def[OF gr]] ground_as[unfolded is_ground_atm_list_def] ground_cs as_len less_atm_ground unfolding strictly_maximal_wrt_def by clarsimp (fastforce simp: is_ground_cls_as_atms)+ then have ll: "\i < n. strictly_maximal_wrt (As ! i \a \) (Cs ! i \ \)" by (simp add: ground_as ground_cs as_len) have ground_e: "is_ground_cls E" using ground_d ground_cs cs_len unfolding e is_ground_cls_def by simp (metis in_mset_sum_list2 in_set_conv_nth) show ?thesis using cas da aas as e ground_e ord_resolve.intros[OF cas_len cs_len aas_len as_len nz casi aas_not_empt \_p fo_elig ll sel_empt] by auto qed end end