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,1209 +1,1267 @@ (* 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) 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.order.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.order.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.order.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" + 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,1301 +1,1414 @@ (* 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 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 \)" + 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 - 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 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 \ ((\# (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 \# \# (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.order.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 exists_compose: "\x. P (f x) \ \y. P y" by meson 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 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 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 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 \# \# (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: "\# (mset Cs) \# \# (mset CAs)" using subseteq_list_Union_mset cas_len cs_len by force then have cs_sub_cas: "\# (mset Cs) \# \# (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 (\# (mset Cs) + D)" using gr_cs gr_d by auto with e have "E = \# (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, hide_lams) List.finite_set finite_imageI finite_set_mset image_iff) moreover then obtain \ where \_p: "\ \ \ = \ \ \" by (metis (mono_tags, hide_lams) 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' = ((\# (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' \ \ = ((\# (mset Cs0')) + D0') \ (\ \ \)" unfolding E0'_def by auto also have "\ = (\# (mset Cs0') + D0') \ (\ \ \)" using \\ by auto also have "\ = (\# (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 diff --git a/thys/Ordered_Resolution_Prover/FO_Ordered_Resolution_Prover.thy b/thys/Ordered_Resolution_Prover/FO_Ordered_Resolution_Prover.thy --- a/thys/Ordered_Resolution_Prover/FO_Ordered_Resolution_Prover.thy +++ b/thys/Ordered_Resolution_Prover/FO_Ordered_Resolution_Prover.thy @@ -1,1548 +1,1359 @@ (* Title: An Ordered Resolution Prover for First-Order Clauses Author: Anders Schlichtkrull , 2016, 2017 Author: Jasmin Blanchette , 2014, 2017 Author: Dmitriy Traytel , 2014 Maintainer: Anders Schlichtkrull *) section \An Ordered Resolution Prover for First-Order Clauses\ theory FO_Ordered_Resolution_Prover imports FO_Ordered_Resolution 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 RP prover defined in Figure 5 and its related lemmas and theorems, including Lemmas 4.10 and 4.11 and Theorem 4.13 (completeness). \ definition is_least :: "(nat \ bool) \ nat \ bool" where "is_least P n \ P n \ (\n' < n. \ P n')" lemma least_exists: "P n \ \n. is_least P n" using exists_least_iff unfolding is_least_def by auto text \ The following corresponds to page 42 and 43 of Section 4.3, from the explanation of RP to Lemma 4.10. \ type_synonym 'a state = "'a clause set \ 'a clause set \ 'a clause set" locale FO_resolution_prover = FO_resolution subst_atm id_subst comp_subst renamings_apart atm_of_atms mgu less_atm + selection S for S :: "('a :: wellorder) clause \ 'a clause" and subst_atm :: "'a \ 's \ 'a" and id_subst :: "'s" and comp_subst :: "'s \ 's \ 's" and renamings_apart :: "'a clause list \ 's list" and atm_of_atms :: "'a list \ 'a" and mgu :: "'a set set \ 's option" and less_atm :: "'a \ 'a \ bool" + assumes - sel_stable: "\\ C. is_renaming \ \ S (C \ \) = S C \ \" and - less_atm_ground: "is_ground_atm A \ is_ground_atm B \ less_atm A B \ A < B" + sel_stable: "\\ C. is_renaming \ \ S (C \ \) = S C \ \" begin -lemma ground_ord_resolve_ground: - assumes - 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 selection_axioms 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 - fun N_of_state :: "'a state \ 'a clause set" where "N_of_state (N, P, Q) = N" fun P_of_state :: "'a state \ 'a clause set" where "P_of_state (N, P, Q) = P" text \ \O\ denotes relation composition in Isabelle, so the formalization uses \Q\ instead. \ fun Q_of_state :: "'a state \ 'a clause set" where "Q_of_state (N, P, Q) = Q" abbreviation clss_of_state :: "'a state \ 'a clause set" where "clss_of_state St \ N_of_state St \ P_of_state St \ Q_of_state St" abbreviation grounding_of_state :: "'a state \ 'a clause set" where "grounding_of_state St \ grounding_of_clss (clss_of_state St)" interpretation ord_FO_resolution: inference_system "ord_FO_\ S" . text \ The following inductive predicate formalizes the resolution prover in Figure 5. \ inductive RP :: "'a state \ 'a state \ bool" (infix "\" 50) where tautology_deletion: "Neg A \# C \ Pos A \# C \ (N \ {C}, P, Q) \ (N, P, Q)" | forward_subsumption: "D \ P \ Q \ subsumes D C \ (N \ {C}, P, Q) \ (N, P, Q)" | backward_subsumption_P: "D \ N \ strictly_subsumes D C \ (N, P \ {C}, Q) \ (N, P, Q)" | backward_subsumption_Q: "D \ N \ strictly_subsumes D C \ (N, P, Q \ {C}) \ (N, P, Q)" | forward_reduction: "D + {#L'#} \ P \ Q \ - L = L' \l \ \ D \ \ \# C \ (N \ {C + {#L#}}, P, Q) \ (N \ {C}, P, Q)" | backward_reduction_P: "D + {#L'#} \ N \ - L = L' \l \ \ D \ \ \# C \ (N, P \ {C + {#L#}}, Q) \ (N, P \ {C}, Q)" | backward_reduction_Q: "D + {#L'#} \ N \ - L = L' \l \ \ D \ \ \# C \ (N, P, Q \ {C + {#L#}}) \ (N, P \ {C}, Q)" | clause_processing: "(N \ {C}, P, Q) \ (N, P \ {C}, Q)" | inference_computation: "N = concls_of (ord_FO_resolution.inferences_between Q C) \ ({}, P \ {C}, Q) \ (N, P, Q \ {C})" lemma final_RP: "\ ({}, {}, Q) \ St" by (auto elim: RP.cases) definition Sup_state :: "'a state llist \ 'a state" where "Sup_state Sts = (Sup_llist (lmap N_of_state Sts), Sup_llist (lmap P_of_state Sts), Sup_llist (lmap Q_of_state Sts))" definition Liminf_state :: "'a state llist \ 'a state" where "Liminf_state Sts = (Liminf_llist (lmap N_of_state Sts), Liminf_llist (lmap P_of_state Sts), Liminf_llist (lmap Q_of_state Sts))" context fixes Sts Sts' :: "'a state llist" assumes Sts: "lfinite Sts" "lfinite Sts'" "\ lnull Sts" "\ lnull Sts'" "llast Sts' = llast Sts" begin lemma N_of_Liminf_state_fin: "N_of_state (Liminf_state Sts') = N_of_state (Liminf_state Sts)" and P_of_Liminf_state_fin: "P_of_state (Liminf_state Sts') = P_of_state (Liminf_state Sts)" and Q_of_Liminf_state_fin: "Q_of_state (Liminf_state Sts') = Q_of_state (Liminf_state Sts)" using Sts by (simp_all add: Liminf_state_def lfinite_Liminf_llist llast_lmap) lemma Liminf_state_fin: "Liminf_state Sts' = Liminf_state Sts" using N_of_Liminf_state_fin P_of_Liminf_state_fin Q_of_Liminf_state_fin by (simp add: Liminf_state_def) end context fixes Sts Sts' :: "'a state llist" assumes Sts: "\ lfinite Sts" "emb Sts Sts'" begin lemma N_of_Liminf_state_inf: "N_of_state (Liminf_state Sts') \ N_of_state (Liminf_state Sts)" and P_of_Liminf_state_inf: "P_of_state (Liminf_state Sts') \ P_of_state (Liminf_state Sts)" and Q_of_Liminf_state_inf: "Q_of_state (Liminf_state Sts') \ Q_of_state (Liminf_state Sts)" using Sts by (simp_all add: Liminf_state_def emb_Liminf_llist_infinite emb_lmap) lemma clss_of_Liminf_state_inf: "clss_of_state (Liminf_state Sts') \ clss_of_state (Liminf_state Sts)" using N_of_Liminf_state_inf P_of_Liminf_state_inf Q_of_Liminf_state_inf by blast end definition fair_state_seq :: "'a state llist \ bool" where "fair_state_seq Sts \ N_of_state (Liminf_state Sts) = {} \ P_of_state (Liminf_state Sts) = {}" text \ The following formalizes Lemma 4.10. \ context fixes Sts :: "'a state llist" begin definition S_Q :: "'a clause \ 'a clause" where "S_Q = S_M S (Q_of_state (Liminf_state Sts))" interpretation sq: selection S_Q unfolding S_Q_def using S_M_selects_subseteq S_M_selects_neg_lits selection_axioms by unfold_locales auto interpretation gr: ground_resolution_with_selection S_Q by unfold_locales interpretation sr: standard_redundancy_criterion_reductive gr.ord_\ by unfold_locales interpretation sr: standard_redundancy_criterion_counterex_reducing gr.ord_\ "ground_resolution_with_selection.INTERP S_Q" by unfold_locales text \ The extension of ordered resolution mentioned in 4.10. We let it consist of all sound rules. \ definition ground_sound_\:: "'a inference set" where "ground_sound_\ = {Infer CC D E | CC D E. (\I. I \m CC \ I \ D \ I \ E)}" text \ We prove that we indeed defined an extension. \ lemma gd_ord_\_ngd_ord_\: "gr.ord_\ \ ground_sound_\" unfolding ground_sound_\_def using gr.ord_\_def gr.ord_resolve_sound by fastforce lemma sound_ground_sound_\: "sound_inference_system ground_sound_\" unfolding sound_inference_system_def ground_sound_\_def by auto lemma sat_preserving_ground_sound_\: "sat_preserving_inference_system ground_sound_\" using sound_ground_sound_\ sat_preserving_inference_system.intro sound_inference_system.\_sat_preserving by blast definition sr_ext_Ri :: "'a clause set \ 'a inference set" where "sr_ext_Ri N = sr.Ri N \ (ground_sound_\ - gr.ord_\)" interpretation sr_ext: - sat_preserving_redundancy_criterion "ground_sound_\" "sr.Rf" "sr_ext_Ri" + sat_preserving_redundancy_criterion ground_sound_\ sr.Rf sr_ext_Ri unfolding sat_preserving_redundancy_criterion_def sr_ext_Ri_def using sat_preserving_ground_sound_\ redundancy_criterion_standard_extension gd_ord_\_ngd_ord_\ sr.redundancy_criterion_axioms by auto lemma strict_subset_subsumption_redundant_clause: assumes sub: "D \ \ \# C" and ground_\: "is_ground_subst \" shows "C \ sr.Rf (grounding_of_cls D)" proof - from sub have "\I. I \ D \ \ \ I \ C" unfolding true_cls_def by blast moreover have "C > D \ \" using sub by (simp add: subset_imp_less_mset) moreover have "D \ \ \ grounding_of_cls D" using ground_\ by (metis (mono_tags) mem_Collect_eq substitution_ops.grounding_of_cls_def) ultimately have "set_mset {#D \ \#} \ grounding_of_cls D" "(\I. I \m {#D \ \#} \ I \ C)" "(\D'. D' \# {#D \ \#} \ D' < C)" by auto then show ?thesis using sr.Rf_def by blast qed lemma strict_subset_subsumption_redundant_clss: assumes "D \ \ \# C" and "is_ground_subst \" and "D \ CC" shows "C \ sr.Rf (grounding_of_clss CC)" using assms proof - have "C \ sr.Rf (grounding_of_cls D)" using strict_subset_subsumption_redundant_clause assms by auto then show ?thesis using assms unfolding grounding_of_clss_def by (metis (no_types) sr.Rf_mono sup_ge1 SUP_absorb contra_subsetD) qed lemma strict_subset_subsumption_grounding_redundant_clss: assumes D\_subset_C: "D \ \ \# C" and D_in_St: "D \ CC" shows "grounding_of_cls C \ sr.Rf (grounding_of_clss CC)" proof fix C\ assume "C\ \ grounding_of_cls C" then obtain \ where \_p: "C\ = C \ \ \ is_ground_subst \" unfolding grounding_of_cls_def by auto have D\\C\: "D \ \ \ \ \# C \ \" using D\_subset_C subst_subset_mono by auto then show "C\ \ sr.Rf (grounding_of_clss CC)" using \_p strict_subset_subsumption_redundant_clss[of D "\ \ \" "C \ \"] D_in_St by auto qed -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 - lemma derive_if_remove_subsumed: assumes "D \ clss_of_state St" and "subsumes D C" shows "sr_ext.derive (grounding_of_state St \ grounding_of_cls C) (grounding_of_state St)" proof - from assms obtain \ where "D \ \ = C \ D \ \ \# C" by (auto simp: subsumes_def subset_mset_def) then have "D \ \ = C \ D \ \ \# C" by (simp add: subset_mset_def) then show ?thesis proof assume "D \ \ = C" then have "grounding_of_cls C \ grounding_of_cls D" using subst_cls_eq_grounding_of_cls_subset_eq by simp then have "(grounding_of_state St \ grounding_of_cls C) = grounding_of_state St" using assms unfolding grounding_of_clss_def by auto then show ?thesis by (auto intro: sr_ext.derive.intros) next assume a: "D \ \ \# C" then have "grounding_of_cls C \ sr.Rf (grounding_of_state St)" using strict_subset_subsumption_grounding_redundant_clss assms by auto then show ?thesis unfolding grounding_of_clss_def by (force intro: sr_ext.derive.intros) qed qed lemma reduction_in_concls_of: assumes "C\ \ grounding_of_cls C" and "D + {#L'#} \ CC" and "- L = L' \l \" and "D \ \ \# C" shows "C\ \ concls_of (sr_ext.inferences_from (grounding_of_clss (CC \ {C + {#L#}})))" proof - from assms obtain \ where \_p: "C\ = C \ \ \ is_ground_subst \" unfolding grounding_of_cls_def by auto define \ where - "\ = Infer {#(C + {#L#})\ \#} ((D + {#L'#}) \ \ \ \) (C \ \)" + "\ = Infer {#(C + {#L#}) \ \#} ((D + {#L'#}) \ \ \ \) (C \ \)" have "(D + {#L'#}) \ \ \ \ \ grounding_of_clss (CC \ {C + {#L#}})" unfolding grounding_of_clss_def grounding_of_cls_def by (rule UN_I[of "D + {#L'#}"], use assms(2) in simp, metis (mono_tags, lifting) \_p is_ground_comp_subst mem_Collect_eq subst_cls_comp_subst) moreover have "(C + {#L#}) \ \ \ grounding_of_clss (CC \ {C + {#L#}})" using \_p unfolding grounding_of_clss_def grounding_of_cls_def by auto moreover have "\I. I \ D \ \ \ \ + {#- (L \l \)#} \ I \ C \ \ + {#L \l \#} \ I \ D \ \ \ \ + C \ \" by auto then have "\I. I \ (D + {#L'#}) \ \ \ \ \ I \ (C + {#L#}) \ \ \ I \ D \ \ \ \ + C \ \" using assms by (metis add_mset_add_single subst_cls_add_mset subst_cls_union subst_minus) then have "\I. I \ (D + {#L'#}) \ \ \ \ \ I \ (C + {#L#}) \ \ \ I \ C \ \" using assms by (metis (no_types, lifting) subset_mset.le_iff_add subst_cls_union true_cls_union) then have "\I. I \m {#(D + {#L'#}) \ \ \ \#} \ I \ (C + {#L#}) \ \ \ I \ C \ \" by (meson true_cls_mset_singleton) ultimately have "\ \ sr_ext.inferences_from (grounding_of_clss (CC \ {C + {#L#}}))" unfolding sr_ext.inferences_from_def unfolding ground_sound_\_def infer_from_def \_def by auto then have "C \ \ \ concls_of (sr_ext.inferences_from (grounding_of_clss (CC \ {C + {#L#}})))" using image_iff unfolding \_def by fastforce then show "C\ \ concls_of (sr_ext.inferences_from (grounding_of_clss (CC \ {C + {#L#}})))" using \_p by auto qed lemma reduction_derivable: assumes "D + {#L'#} \ CC" and "- L = L' \l \" and "D \ \ \# C" shows "sr_ext.derive (grounding_of_clss (CC \ {C + {#L#}})) (grounding_of_clss (CC \ {C}))" proof - from assms have "grounding_of_clss (CC \ {C}) - grounding_of_clss (CC \ {C + {#L#}}) \ concls_of (sr_ext.inferences_from (grounding_of_clss (CC \ {C + {#L#}})))" using reduction_in_concls_of unfolding grounding_of_clss_def by auto moreover have "grounding_of_cls (C + {#L#}) \ sr.Rf (grounding_of_clss (CC \ {C}))" using strict_subset_subsumption_grounding_redundant_clss[of C "id_subst"] by auto then have "grounding_of_clss (CC \ {C + {#L#}}) - grounding_of_clss (CC \ {C}) \ sr.Rf (grounding_of_clss (CC \ {C}))" unfolding grounding_of_clss_def by auto ultimately show "sr_ext.derive (grounding_of_clss (CC \ {C + {#L#}})) (grounding_of_clss (CC \ {C}))" using sr_ext.derive.intros[of "grounding_of_clss (CC \ {C})" "grounding_of_clss (CC \ {C + {#L#}})"] by auto qed text \ The following corresponds the part of Lemma 4.10 that states we have a theorem proving process: \ lemma RP_ground_derive: "St \ St' \ sr_ext.derive (grounding_of_state St) (grounding_of_state St')" proof (induction rule: RP.induct) case (tautology_deletion A C N P Q) { fix C\ assume "C\ \ grounding_of_cls C" then obtain \ where "C\ = C \ \" unfolding grounding_of_cls_def by auto then have "Neg (A \a \) \# C\ \ Pos (A \a \) \# C\" using tautology_deletion Neg_Melem_subst_atm_subst_cls Pos_Melem_subst_atm_subst_cls by auto then have "C\ \ sr.Rf (grounding_of_state (N, P, Q))" using sr.tautology_Rf by auto } then have "grounding_of_state (N \ {C}, P, Q) - grounding_of_state (N, P, Q) \ sr.Rf (grounding_of_state (N, P, Q))" unfolding grounding_of_clss_def by auto moreover have "grounding_of_state (N, P, Q) - grounding_of_state (N \ {C}, P, Q) = {}" unfolding grounding_of_clss_def by auto ultimately show ?case using sr_ext.derive.intros[of "grounding_of_state (N, P, Q)" "grounding_of_state (N \ {C}, P, Q)"] by auto next case (forward_subsumption D P Q C N) then show ?case using derive_if_remove_subsumed[of D "(N, P, Q)" C] unfolding grounding_of_clss_def by (simp add: sup_commute sup_left_commute) next case (backward_subsumption_P D N C P Q) then show ?case using derive_if_remove_subsumed[of D "(N, P, Q)" C] strictly_subsumes_def unfolding grounding_of_clss_def by (simp add: sup_commute sup_left_commute) next case (backward_subsumption_Q D N C P Q) then show ?case using derive_if_remove_subsumed[of D "(N, P, Q)" C] strictly_subsumes_def unfolding grounding_of_clss_def by (simp add: sup_commute sup_left_commute) next case (forward_reduction D L' P Q L \ C N) then show ?case using reduction_derivable[of _ _ "N \ P \ Q"] by force next case (backward_reduction_P D L' N L \ C P Q) then show ?case using reduction_derivable[of _ _ "N \ P \ Q"] by force next case (backward_reduction_Q D L' N L \ C P Q) then show ?case using reduction_derivable[of _ _ "N \ P \ Q"] by force next case (clause_processing N C P Q) then show ?case using sr_ext.derive.intros by auto next case (inference_computation N Q C P) { fix E\ assume "E\ \ grounding_of_clss N" then obtain \ E where E_\_p: "E\ = E \ \ \ E \ N \ is_ground_subst \" unfolding grounding_of_clss_def grounding_of_cls_def by auto then have E_concl: "E \ concls_of (ord_FO_resolution.inferences_between Q C)" using inference_computation by auto then obtain \ where \_p: "\ \ ord_FO_\ S \ infer_from (Q \ {C}) \ \ C \# prems_of \ \ concl_of \ = E" unfolding ord_FO_resolution.inferences_between_def by auto then obtain CC CAs D AAs As \ where \_p2: "\ = Infer CC D E \ ord_resolve_rename S CAs D AAs As \ E \ mset CAs = CC" unfolding ord_FO_\_def by auto define \ where "\ = hd (renamings_apart (D # CAs))" define \s where "\s = tl (renamings_apart (D # CAs))" define \_ground where "\_ground = Infer (mset (CAs \\cl \s) \cm \ \cm \) (D \ \ \ \ \ \) (E \ \)" have "\I. I \m mset (CAs \\cl \s) \cm \ \cm \ \ I \ D \ \ \ \ \ \ \ I \ E \ \" using ord_resolve_rename_ground_inst_sound[of _ _ _ _ _ _ _ _ _ _ \] \_def \s_def E_\_p \_p2 by auto then have "\_ground \ {Infer cc d e | cc d e. \I. I \m cc \ I \ d \ I \ e}" unfolding \_ground_def by auto moreover have "set_mset (prems_of \_ground) \ grounding_of_state ({}, P \ {C}, Q)" proof - have "D = C \ D \ Q" unfolding \_ground_def using E_\_p \_p2 \_p unfolding infer_from_def unfolding grounding_of_clss_def grounding_of_cls_def by simp then have "D \ \ \ \ \ \ \ grounding_of_cls C \ (\x \ Q. D \ \ \ \ \ \ \ grounding_of_cls x)" using E_\_p unfolding grounding_of_cls_def by (metis (mono_tags, lifting) is_ground_comp_subst mem_Collect_eq subst_cls_comp_subst) then have "(D \ \ \ \ \ \ \ grounding_of_cls C \ (\x \ P. D \ \ \ \ \ \ \ grounding_of_cls x) \ (\x \ Q. D \ \ \ \ \ \ \ grounding_of_cls x))" by metis - moreover have "\i < length (CAs \\cl \s \cl \ \cl \). ((CAs \\cl \s \cl \ \cl \) ! i) \ + moreover have "\i < length (CAs \\cl \s \cl \ \cl \). (CAs \\cl \s \cl \ \cl \) ! i \ {C \ \ |\. is_ground_subst \} \ ((\C \ P. {C \ \ | \. is_ground_subst \}) \ (\C\Q. {C \ \ | \. is_ground_subst \}))" proof (rule, rule) fix i assume "i < length (CAs \\cl \s \cl \ \cl \)" then have a: "i < length CAs \ i < length \s" by simp moreover from a have "CAs ! i \ {C} \ Q" using \_p2 \_p unfolding infer_from_def by (metis (no_types, lifting) Un_subset_iff inference.sel(1) set_mset_union sup_commute nth_mem_mset subsetCE) ultimately have "(CAs \\cl \s \cl \ \cl \) ! i \ {C \ \ |\. is_ground_subst \} \ ((CAs \\cl \s \cl \ \cl \) ! i \ (\C\P. {C \ \ |\. is_ground_subst \}) \ (CAs \\cl \s \cl \ \cl \) ! i \ (\C \ Q. {C \ \ | \. is_ground_subst \}))" using E_\_p \_p2 \_p unfolding \_ground_def infer_from_def grounding_of_clss_def grounding_of_cls_def apply - apply (cases "CAs ! i = C") subgoal apply (rule disjI1) apply (rule Set.CollectI) apply (rule_tac x = "(\s ! i) \ \ \ \" in exI) using \s_def using renamings_apart_length by (auto; fail) subgoal apply (rule disjI2) apply (rule disjI2) apply (rule_tac a = "CAs ! i" in UN_I) subgoal by blast subgoal apply (rule Set.CollectI) apply (rule_tac x = "(\s ! i) \ \ \ \" in exI) using \s_def using renamings_apart_length by (auto; fail) done done then show "(CAs \\cl \s \cl \ \cl \) ! i \ {C \ \ |\. is_ground_subst \} \ ((\C \ P. {C \ \ |\. is_ground_subst \}) \ (\C \ Q. {C \ \ |\. is_ground_subst \}))" by blast qed then have "\x \# mset (CAs \\cl \s \cl \ \cl \). x \ {C \ \ |\. is_ground_subst \} \ ((\C \ P. {C \ \ |\. is_ground_subst \}) \ (\C \ Q. {C \ \ |\. is_ground_subst \}))" by (metis (lifting) in_set_conv_nth set_mset_mset) then have "set_mset (mset (CAs \\cl \s) \cm \ \cm \) \ grounding_of_cls C \ grounding_of_clss P \ grounding_of_clss Q" unfolding grounding_of_cls_def grounding_of_clss_def using mset_subst_cls_list_subst_cls_mset by auto ultimately show ?thesis unfolding \_ground_def grounding_of_clss_def by auto qed ultimately have "E \ \ \ concls_of (sr_ext.inferences_from (grounding_of_state ({}, P \ {C}, Q)))" unfolding sr_ext.inferences_from_def inference_system.inferences_from_def ground_sound_\_def infer_from_def - using \_ground_def by (metis (no_types, lifting) imageI inference.sel(3) mem_Collect_eq) + using \_ground_def by (metis (mono_tags, lifting) image_eqI inference.sel(3) mem_Collect_eq) then have "E\ \ concls_of (sr_ext.inferences_from (grounding_of_state ({}, P \ {C}, Q)))" using E_\_p by auto } then have "grounding_of_state (N, P, Q \ {C}) - grounding_of_state ({}, P \ {C}, Q) \ concls_of (sr_ext.inferences_from (grounding_of_state ({}, P \ {C}, Q)))" unfolding grounding_of_clss_def by auto moreover have "grounding_of_state ({}, P \ {C}, Q) - grounding_of_state (N, P, Q \ {C}) = {}" unfolding grounding_of_clss_def by auto ultimately show ?case using sr_ext.derive.intros[of "(grounding_of_state (N, P, Q \ {C}))" "(grounding_of_state ({}, P \ {C}, Q))"] by auto qed text \ A useful consequence: \ -theorem RP_model: - "St \ St' \ I \s grounding_of_state St' \ I \s grounding_of_state St" +theorem RP_model: "St \ St' \ I \s grounding_of_state St' \ I \s grounding_of_state St" proof (drule RP_ground_derive, erule sr_ext.derive.cases, hypsubst) let ?gSt = "grounding_of_state St" and ?gSt' = "grounding_of_state St'" assume deduct: "?gSt' - ?gSt \ concls_of (sr_ext.inferences_from ?gSt)" (is "_ \ ?concls") and delete: "?gSt - ?gSt' \ sr.Rf ?gSt'" show "I \s ?gSt' \ I \s ?gSt" proof assume bef: "I \s ?gSt" then have "I \s ?concls" unfolding ground_sound_\_def inference_system.inferences_from_def true_clss_def true_cls_mset_def by (auto simp add: image_def infer_from_def dest!: spec[of _ I]) then have diff: "I \s ?gSt' - ?gSt" using deduct by (blast intro: true_clss_mono) then show "I \s ?gSt'" using bef unfolding true_clss_def by blast next assume aft: "I \s ?gSt'" have "I \s ?gSt' \ sr.Rf ?gSt'" by (rule sr.Rf_model) (smt Diff_eq_empty_iff Diff_subset Un_Diff aft standard_redundancy_criterion.Rf_mono sup_bot.right_neutral sup_ge1 true_clss_mono) then have "I \s sr.Rf ?gSt'" using true_clss_union by blast then have diff: "I \s ?gSt - ?gSt'" using delete by (blast intro: true_clss_mono) then show "I \s ?gSt" using aft unfolding true_clss_def by blast qed qed text \ Another formulation of the part of Lemma 4.10 that states we have a theorem proving process: \ lemma ground_derive_chain: "chain (\) Sts \ chain sr_ext.derive (lmap grounding_of_state Sts)" using RP_ground_derive by (simp add: chain_lmap[of "(\)"]) text \ The following is used prove to Lemma 4.11: \ -lemma in_Sup_llist_in_nth: "C \ Sup_llist Gs \ \j. enat j < llength Gs \ C \ lnth Gs j" - unfolding Sup_llist_def by auto - \ \Note: Gs is called Ns in the chapter\ - lemma Sup_llist_grounding_of_state_ground: assumes "C \ Sup_llist (lmap grounding_of_state Sts)" shows "is_ground_cls C" proof - have "\j. enat j < llength (lmap grounding_of_state Sts) \ C \ lnth (lmap grounding_of_state Sts) j" - using assms in_Sup_llist_in_nth by fast - then obtain j where - "enat j < llength (lmap grounding_of_state Sts)" - "C \ lnth (lmap grounding_of_state Sts) j" - by blast + using assms Sup_llist_imp_exists_index by fast then show ?thesis unfolding grounding_of_clss_def grounding_of_cls_def by auto qed lemma Liminf_grounding_of_state_ground: "C \ Liminf_llist (lmap grounding_of_state Sts) \ is_ground_cls C" using Liminf_llist_subset_Sup_llist[of "lmap grounding_of_state Sts"] Sup_llist_grounding_of_state_ground by blast lemma in_Sup_llist_in_Sup_state: assumes "C \ Sup_llist (lmap grounding_of_state Sts)" shows "\D \. D \ clss_of_state (Sup_state Sts) \ D \ \ = C \ is_ground_subst \" proof - from assms obtain i where i_p: "enat i < llength Sts \ C \ lnth (lmap grounding_of_state Sts) i" - using in_Sup_llist_in_nth by fastforce + using Sup_llist_imp_exists_index by fastforce then obtain D \ where "D \ clss_of_state (lnth Sts i) \ D \ \ = C \ is_ground_subst \" using assms unfolding grounding_of_clss_def grounding_of_cls_def by fastforce then have "D \ clss_of_state (Sup_state Sts) \ D \ \ = C \ is_ground_subst \" using i_p unfolding Sup_state_def by (metis (no_types, lifting) UnCI UnE contra_subsetD N_of_state.simps P_of_state.simps Q_of_state.simps llength_lmap lnth_lmap lnth_subset_Sup_llist) then show ?thesis by auto qed lemma N_of_state_Liminf: "N_of_state (Liminf_state Sts) = Liminf_llist (lmap N_of_state Sts)" and P_of_state_Liminf: "P_of_state (Liminf_state Sts) = Liminf_llist (lmap P_of_state Sts)" unfolding Liminf_state_def by auto lemma eventually_removed_from_N: assumes d_in: "D \ N_of_state (lnth Sts i)" and fair: "fair_state_seq Sts" and i_Sts: "enat i < llength Sts" shows "\l. D \ N_of_state (lnth Sts l) \ D \ N_of_state (lnth Sts (Suc l)) \ i \ l \ enat (Suc l) < llength Sts" proof (rule ccontr) assume a: "\ ?thesis" have "i \ l \ enat l < llength Sts \ D \ N_of_state (lnth Sts l)" for l using d_in by (induction l, blast, metis a Suc_ile_eq le_SucE less_imp_le) then have "D \ Liminf_llist (lmap N_of_state Sts)" unfolding Liminf_llist_def using i_Sts by auto then show False using fair unfolding fair_state_seq_def by (simp add: N_of_state_Liminf) qed lemma eventually_removed_from_P: assumes d_in: "D \ P_of_state (lnth Sts i)" and fair: "fair_state_seq Sts" and i_Sts: "enat i < llength Sts" shows "\l. D \ P_of_state (lnth Sts l) \ D \ P_of_state (lnth Sts (Suc l)) \ i \ l \ enat (Suc l) < llength Sts" proof (rule ccontr) assume a: "\ ?thesis" have "i \ l \ enat l < llength Sts \ D \ P_of_state (lnth Sts l)" for l using d_in by (induction l, blast, metis a Suc_ile_eq le_SucE less_imp_le) then have "D \ Liminf_llist (lmap P_of_state Sts)" unfolding Liminf_llist_def using i_Sts by auto then show False using fair unfolding fair_state_seq_def by (simp add: P_of_state_Liminf) qed lemma instance_if_subsumed_and_in_limit: assumes deriv: "chain (\) Sts" and ns: "Gs = lmap grounding_of_state Sts" and c: "C \ Liminf_llist Gs - sr.Rf (Liminf_llist Gs)" and d: "D \ clss_of_state (lnth Sts i)" "enat i < llength Sts" "subsumes D C" shows "\\. D \ \ = C \ is_ground_subst \" proof - let ?Ps = "\i. P_of_state (lnth Sts i)" let ?Qs = "\i. Q_of_state (lnth Sts i)" have ground_C: "is_ground_cls C" using c using Liminf_grounding_of_state_ground ns by auto have derivns: "chain sr_ext.derive Gs" using ground_derive_chain deriv ns by auto have "\\. D \ \ = C" proof (rule ccontr) assume "\\. D \ \ = C" moreover from d(3) obtain \_proto where "D \ \_proto \# C" unfolding subsumes_def by blast then obtain \ where \_p: "D \ \ \# C \ is_ground_subst \" using ground_C by (metis is_ground_cls_mono make_ground_subst subset_mset.order_refl) ultimately have subsub: "D \ \ \# C" using subset_mset.le_imp_less_or_eq by auto moreover have "is_ground_subst \" using \_p by auto moreover have "D \ clss_of_state (lnth Sts i)" using d by auto ultimately have "C \ sr.Rf (grounding_of_state (lnth Sts i))" using strict_subset_subsumption_redundant_clss by auto then have "C \ sr.Rf (Sup_llist Gs)" using d ns by (smt contra_subsetD llength_lmap lnth_lmap lnth_subset_Sup_llist sr.Rf_mono) then have "C \ sr.Rf (Liminf_llist Gs)" unfolding ns using local.sr_ext.Rf_limit_Sup derivns ns by auto then show False using c by auto qed then obtain \ where "D \ \ = C \ is_ground_subst \" using ground_C by (metis make_ground_subst) then show ?thesis by auto qed lemma from_Q_to_Q_inf: assumes deriv: "chain (\) Sts" and fair: "fair_state_seq Sts" and ns: "Gs = lmap grounding_of_state Sts" and c: "C \ Liminf_llist Gs - sr.Rf (Liminf_llist Gs)" and d: "D \ Q_of_state (lnth Sts i)" "enat i < llength Sts" "subsumes D C" and d_least: "\E \ {E. E \ (clss_of_state (Sup_state Sts)) \ subsumes E C}. \ strictly_subsumes E D" shows "D \ Q_of_state (Liminf_state Sts)" proof - let ?Ps = "\i. P_of_state (lnth Sts i)" let ?Qs = "\i. Q_of_state (lnth Sts i)" have ground_C: "is_ground_cls C" using c using Liminf_grounding_of_state_ground ns by auto have derivns: "chain sr_ext.derive Gs" using ground_derive_chain deriv ns by auto have "\\. D \ \ = C \ is_ground_subst \" using instance_if_subsumed_and_in_limit[OF deriv] c d unfolding ns by blast then obtain \ where \: "D \ \ = C" "is_ground_subst \" by auto have in_Sts_in_Sts_Suc: "\l \ i. enat (Suc l) < llength Sts \ D \ Q_of_state (lnth Sts l) \ D \ Q_of_state (lnth Sts (Suc l))" proof (rule, rule, rule, rule) fix l assume len: "i \ l" and llen: "enat (Suc l) < llength Sts" and d_in_q: "D \ Q_of_state (lnth Sts l)" have "lnth Sts l \ lnth Sts (Suc l)" using llen deriv chain_lnth_rel by blast then show "D \ Q_of_state (lnth Sts (Suc l))" proof (cases rule: RP.cases) case (backward_subsumption_Q D' N D_removed P Q) moreover { assume "D_removed = D" then obtain D_subsumes where D_subsumes_p: "D_subsumes \ N \ strictly_subsumes D_subsumes D" using backward_subsumption_Q by auto moreover from D_subsumes_p have "subsumes D_subsumes C" using d subsumes_trans unfolding strictly_subsumes_def by blast moreover from backward_subsumption_Q have "D_subsumes \ clss_of_state (Sup_state Sts)" using D_subsumes_p llen by (metis (no_types) UnI1 N_of_state.simps llength_lmap lnth_lmap lnth_subset_Sup_llist rev_subsetD Sup_state_def) ultimately have False using d_least unfolding subsumes_def by auto } ultimately show ?thesis using d_in_q by auto next case (backward_reduction_Q E L' N L \ D' P Q) { assume "D' + {#L#} = D" then have D'_p: "strictly_subsumes D' D \ D' \ ?Ps (Suc l)" using subset_strictly_subsumes[of D' D] backward_reduction_Q by auto then have subc: "subsumes D' C" using d(3) subsumes_trans unfolding strictly_subsumes_def by auto from D'_p have "D' \ clss_of_state (Sup_state Sts)" using llen by (metis (no_types) UnI1 P_of_state.simps llength_lmap lnth_lmap lnth_subset_Sup_llist subsetCE sup_ge2 Sup_state_def) then have False using d_least D'_p subc by auto } then show ?thesis using backward_reduction_Q d_in_q by auto qed (use d_in_q in auto) qed have D_in_Sts: "D \ Q_of_state (lnth Sts l)" and D_in_Sts_Suc: "D \ Q_of_state (lnth Sts (Suc l))" if l_i: "l \ i" and enat: "enat (Suc l) < llength Sts" for l proof - show "D \ Q_of_state (lnth Sts l)" using l_i enat apply (induction "l - i" arbitrary: l) subgoal using d by auto subgoal using d(1) in_Sts_in_Sts_Suc by (metis (no_types, lifting) Suc_ile_eq add_Suc_right add_diff_cancel_left' le_SucE le_Suc_ex less_imp_le) done then show "D \ Q_of_state (lnth Sts (Suc l))" using l_i enat in_Sts_in_Sts_Suc by blast qed have "i \ x \ enat x < llength Sts \ D \ Q_of_state (lnth Sts x)" for x apply (cases x) subgoal using d(1) by (auto intro!: exI[of _ i] simp: less_Suc_eq) subgoal for x' using d(1) D_in_Sts_Suc[of x'] by (cases \i \ x'\) (auto simp: not_less_eq_eq) done then have "D \ Liminf_llist (lmap Q_of_state Sts)" unfolding Liminf_llist_def by (auto intro!: exI[of _ i] simp: d) then show ?thesis unfolding Liminf_state_def by auto qed lemma from_P_to_Q: assumes deriv: "chain (\) Sts" and fair: "fair_state_seq Sts" and ns: "Gs = lmap grounding_of_state Sts" and c: "C \ Liminf_llist Gs - sr.Rf (Liminf_llist Gs)" and d: "D \ P_of_state (lnth Sts i)" "enat i < llength Sts" "subsumes D C" and d_least: "\E \ {E. E \ (clss_of_state (Sup_state Sts)) \ subsumes E C}. \ strictly_subsumes E D" shows "\l. D \ Q_of_state (lnth Sts l) \ enat l < llength Sts" proof - let ?Ns = "\i. N_of_state (lnth Sts i)" let ?Ps = "\i. P_of_state (lnth Sts i)" let ?Qs = "\i. Q_of_state (lnth Sts i)" have ground_C: "is_ground_cls C" using c using Liminf_grounding_of_state_ground ns by auto have derivns: "chain sr_ext.derive Gs" using ground_derive_chain deriv ns by auto have "\\. D \ \ = C \ is_ground_subst \" using instance_if_subsumed_and_in_limit[OF deriv] ns c d by blast then obtain \ where \: "D \ \ = C" "is_ground_subst \" by auto obtain l where l_p: "D \ P_of_state (lnth Sts l) \ D \ P_of_state (lnth Sts (Suc l)) \ i \ l \ enat (Suc l) < llength Sts" using fair using eventually_removed_from_P d unfolding ns by auto then have l_Gs: "enat (Suc l) < llength Gs" using ns by auto from l_p have "lnth Sts l \ lnth Sts (Suc l)" using deriv using chain_lnth_rel by auto then show ?thesis proof (cases rule: RP.cases) case (backward_subsumption_P D' N D_twin P Q) note lrhs = this(1,2) and D'_p = this(3,4) then have twins: "D_twin = D" "?Ns (Suc l) = N" "?Ns l = N" "?Ps (Suc l) = P" "?Ps l = P \ {D_twin}" "?Qs (Suc l) = Q" "?Qs l = Q" using l_p by auto note D'_p = D'_p[unfolded twins(1)] then have subc: "subsumes D' C" unfolding strictly_subsumes_def subsumes_def using \ by (metis subst_cls_comp_subst subst_cls_mono_mset) from D'_p have "D' \ clss_of_state (Sup_state Sts)" unfolding twins(2)[symmetric] using l_p by (metis (no_types) UnI1 N_of_state.simps llength_lmap lnth_lmap lnth_subset_Sup_llist subsetCE Sup_state_def) then have False using d_least D'_p subc by auto then show ?thesis by auto next case (backward_reduction_P E L' N L \ D' P Q) then have twins: "D' + {#L#} = D" "?Ns (Suc l) = N" "?Ns l = N" "?Ps (Suc l) = P \ {D'}" "?Ps l = P \ {D' + {#L#}}" "?Qs (Suc l) = Q" "?Qs l = Q" using l_p by auto then have D'_p: "strictly_subsumes D' D \ D' \ ?Ps (Suc l)" using subset_strictly_subsumes[of D' D] by auto then have subc: "subsumes D' C" using d(3) subsumes_trans unfolding strictly_subsumes_def by auto from D'_p have "D' \ clss_of_state (Sup_state Sts)" using l_p by (metis (no_types) UnI1 P_of_state.simps llength_lmap lnth_lmap lnth_subset_Sup_llist subsetCE sup_ge2 Sup_state_def) then have False using d_least D'_p subc by auto then show ?thesis by auto next case (inference_computation N Q D_twin P) then have twins: "D_twin = D" "?Ps (Suc l) = P" "?Ps l = P \ {D_twin}" "?Qs (Suc l) = Q \ {D_twin}" "?Qs l = Q" using l_p by auto then show ?thesis using d \ l_p by auto qed (use l_p in auto) qed -lemma variants_sym: "variants D D' \ variants D' D" - unfolding variants_def by auto - -lemma variants_imp_exists_subtitution: "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 properly_subsume_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_subtitution 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_properly_subsume_variants: - assumes "\ strictly_subsumes E D" and "variants D D'" - shows "\ strictly_subsumes E D'" - using assms properly_subsume_variants variants_sym by auto - lemma from_N_to_P_or_Q: assumes deriv: "chain (\) Sts" and fair: "fair_state_seq Sts" and ns: "Gs = lmap grounding_of_state Sts" and c: "C \ Liminf_llist Gs - sr.Rf (Liminf_llist Gs)" and d: "D \ N_of_state (lnth Sts i)" "enat i < llength Sts" "subsumes D C" and d_least: "\E \ {E. E \ (clss_of_state (Sup_state Sts)) \ subsumes E C}. \ strictly_subsumes E D" shows "\l D' \'. D' \ P_of_state (lnth Sts l) \ Q_of_state (lnth Sts l) \ enat l < llength Sts \ (\E \ {E. E \ (clss_of_state (Sup_state Sts)) \ subsumes E C}. \ strictly_subsumes E D') \ D' \ \' = C \ is_ground_subst \' \ subsumes D' C" proof - let ?Ns = "\i. N_of_state (lnth Sts i)" let ?Ps = "\i. P_of_state (lnth Sts i)" let ?Qs = "\i. Q_of_state (lnth Sts i)" have ground_C: "is_ground_cls C" using c using Liminf_grounding_of_state_ground ns by auto have derivns: "chain sr_ext.derive Gs" using ground_derive_chain deriv ns by auto have "\\. D \ \ = C \ is_ground_subst \" using instance_if_subsumed_and_in_limit[OF deriv] ns c d by blast then obtain \ where \: "D \ \ = C" "is_ground_subst \" by auto from c have no_taut: "\ (\A. Pos A \# C \ Neg A \# C)" using sr.tautology_Rf by auto have "\l. D \ N_of_state (lnth Sts l) \ D \ N_of_state (lnth Sts (Suc l)) \ i \ l \ enat (Suc l) < llength Sts" using fair using eventually_removed_from_N d unfolding ns by auto then obtain l where l_p: "D \ N_of_state (lnth Sts l) \ D \ N_of_state (lnth Sts (Suc l)) \ i \ l \ enat (Suc l) < llength Sts" by auto then have l_Gs: "enat (Suc l) < llength Gs" using ns by auto from l_p have "lnth Sts l \ lnth Sts (Suc l)" using deriv using chain_lnth_rel by auto then show ?thesis proof (cases rule: RP.cases) case (tautology_deletion A D_twin N P Q) then have "D_twin = D" using l_p by auto then have "Pos (A \a \) \# C \ Neg (A \a \) \# C" using tautology_deletion(3,4) \ by (metis Melem_subst_cls eql_neg_lit_eql_atm eql_pos_lit_eql_atm) then have False using no_taut by metis then show ?thesis by blast next case (forward_subsumption D' P Q D_twin N) note lrhs = this(1,2) and D'_p = this(3,4) then have twins: "D_twin = D" "?Ns (Suc l) = N" "?Ns l = N \ {D_twin}" "?Ps (Suc l) = P " "?Ps l = P" "?Qs (Suc l) = Q" "?Qs l = Q" using l_p by auto note D'_p = D'_p[unfolded twins(1)] from D'_p(2) have subs: "subsumes D' C" using d(3) by (blast intro: subsumes_trans) moreover have "D' \ clss_of_state (Sup_state Sts)" using twins D'_p l_p unfolding Sup_state_def by simp (metis (no_types) contra_subsetD llength_lmap lnth_lmap lnth_subset_Sup_llist) ultimately have "\ strictly_subsumes D' D" using d_least by auto then have "subsumes D D'" unfolding strictly_subsumes_def using D'_p by auto then have v: "variants D D'" using D'_p unfolding variants_iff_subsumes by auto then have mini: "\E \ {E \ clss_of_state (Sup_state Sts). subsumes E C}. \ strictly_subsumes E D'" - using d_least D'_p neg_properly_subsume_variants[of _ D D'] by auto + using d_least D'_p neg_strictly_subsumes_variants[of _ D D'] by auto from v have "\\'. D' \ \' = C" - using \ variants_imp_exists_subtitution variants_sym by (metis subst_cls_comp_subst) + using \ variants_imp_exists_substitution variants_sym by (metis subst_cls_comp_subst) then have "\\'. D' \ \' = C \ is_ground_subst \'" using ground_C by (meson make_ground_subst refl) then obtain \' where \'_p: "D' \ \' = C \ is_ground_subst \'" by metis show ?thesis using D'_p twins l_p subs mini \'_p by auto next case (forward_reduction E L' P Q L \ D' N) then have twins: "D' + {#L#} = D" "?Ns (Suc l) = N \ {D'}" "?Ns l = N \ {D' + {#L#}}" "?Ps (Suc l) = P " "?Ps l = P" "?Qs (Suc l) = Q" "?Qs l = Q" using l_p by auto then have D'_p: "strictly_subsumes D' D \ D' \ ?Ns (Suc l)" using subset_strictly_subsumes[of D' D] by auto then have subc: "subsumes D' C" using d(3) subsumes_trans unfolding strictly_subsumes_def by blast from D'_p have "D' \ clss_of_state (Sup_state Sts)" using l_p by (metis (no_types) UnI1 N_of_state.simps llength_lmap lnth_lmap lnth_subset_Sup_llist subsetCE Sup_state_def) then have False using d_least D'_p subc by auto then show ?thesis by auto next case (clause_processing N D_twin P Q) then have twins: "D_twin = D" "?Ns (Suc l) = N" "?Ns l = N \ {D}" "?Ps (Suc l) = P \ {D}" "?Ps l = P" "?Qs (Suc l) = Q" "?Qs l = Q" using l_p by auto then show ?thesis using d \ l_p d_least by blast qed (use l_p in auto) qed lemma eventually_in_Qinf: assumes deriv: "chain (\) Sts" and D_p: "D \ clss_of_state (Sup_state Sts)" "subsumes D C" "\E \ {E. E \ (clss_of_state (Sup_state Sts)) \ subsumes E C}. \ strictly_subsumes E D" and fair: "fair_state_seq Sts" and ns: "Gs = lmap grounding_of_state Sts" and c: "C \ Liminf_llist Gs - sr.Rf (Liminf_llist Gs)" and ground_C: "is_ground_cls C" shows "\D' \'. D' \ Q_of_state (Liminf_state Sts) \ D' \ \' = C \ is_ground_subst \'" proof - let ?Ns = "\i. N_of_state (lnth Sts i)" let ?Ps = "\i. P_of_state (lnth Sts i)" let ?Qs = "\i. Q_of_state (lnth Sts i)" from D_p obtain i where i_p: "i < llength Sts" "D \ ?Ns i \ D \ ?Ps i \ D \ ?Qs i" unfolding Sup_state_def - by simp_all (metis (no_types) in_Sup_llist_in_nth llength_lmap lnth_lmap) + by simp_all (metis (no_types) Sup_llist_imp_exists_index llength_lmap lnth_lmap) have derivns: "chain sr_ext.derive Gs" using ground_derive_chain deriv ns by auto have "\\. D \ \ = C \ is_ground_subst \" using instance_if_subsumed_and_in_limit[OF deriv ns c] D_p i_p by blast then obtain \ where \: "D \ \ = C" "is_ground_subst \" by blast { assume a: "D \ ?Ns i" then obtain D' \' l where D'_p: "D' \ ?Ps l \ ?Qs l" "D' \ \' = C" "enat l < llength Sts" "is_ground_subst \'" "\E \ {E. E \ (clss_of_state (Sup_state Sts)) \ subsumes E C}. \ strictly_subsumes E D'" "subsumes D' C" using from_N_to_P_or_Q deriv fair ns c i_p(1) D_p(2) D_p(3) by blast then obtain l' where l'_p: "D' \ ?Qs l'" "l' < llength Sts" using from_P_to_Q[OF deriv fair ns c _ D'_p(3) D'_p(6) D'_p(5)] by blast then have "D' \ Q_of_state (Liminf_state Sts)" using from_Q_to_Q_inf[OF deriv fair ns c _ l'_p(2)] D'_p by auto then have ?thesis using D'_p by auto } moreover { assume a: "D \ ?Ps i" then obtain l' where l'_p: "D \ ?Qs l'" "l' < llength Sts" using from_P_to_Q[OF deriv fair ns c a i_p(1) D_p(2) D_p(3)] by auto then have "D \ Q_of_state (Liminf_state Sts)" using from_Q_to_Q_inf[OF deriv fair ns c l'_p(1) l'_p(2)] D_p(3) \(1) \(2) D_p(2) by auto then have ?thesis using D_p \ by auto } moreover { assume a: "D \ ?Qs i" then have "D \ Q_of_state (Liminf_state Sts)" using from_Q_to_Q_inf[OF deriv fair ns c a i_p(1)] \ D_p(2,3) by auto then have ?thesis using D_p \ by auto } ultimately show ?thesis using i_p by auto qed text \ The following corresponds to Lemma 4.11: \ lemma fair_imp_Liminf_minus_Rf_subset_ground_Liminf_state: assumes deriv: "chain (\) Sts" and fair: "fair_state_seq Sts" and ns: "Gs = lmap grounding_of_state Sts" shows "Liminf_llist Gs - sr.Rf (Liminf_llist Gs) \ grounding_of_clss (Q_of_state (Liminf_state Sts))" proof let ?Ns = "\i. N_of_state (lnth Sts i)" let ?Ps = "\i. P_of_state (lnth Sts i)" let ?Qs = "\i. Q_of_state (lnth Sts i)" have SQinf: "clss_of_state (Liminf_state Sts) = Liminf_llist (lmap Q_of_state Sts)" using fair unfolding fair_state_seq_def Liminf_state_def by auto fix C assume C_p: "C \ Liminf_llist Gs - sr.Rf (Liminf_llist Gs)" then have "C \ Sup_llist Gs" using Liminf_llist_subset_Sup_llist[of Gs] by blast then obtain D_proto where "D_proto \ clss_of_state (Sup_state Sts) \ subsumes D_proto C" using in_Sup_llist_in_Sup_state unfolding ns subsumes_def by blast then obtain D where D_p: "D \ clss_of_state (Sup_state Sts)" "subsumes D C" "\E \ {E. E \ clss_of_state (Sup_state Sts) \ subsumes E C}. \ strictly_subsumes E D" using strictly_subsumes_has_minimum[of "{E. E \ clss_of_state (Sup_state Sts) \ subsumes E C}"] by auto have ground_C: "is_ground_cls C" using C_p using Liminf_grounding_of_state_ground ns by auto have "\D' \'. D' \ Q_of_state (Liminf_state Sts) \ D' \ \' = C \ is_ground_subst \'" using eventually_in_Qinf[of D C Gs] using D_p(1-3) deriv fair ns C_p ground_C by auto then obtain D' \' where D'_p: "D' \ Q_of_state (Liminf_state Sts) \ D' \ \' = C \ is_ground_subst \'" by blast then have "D' \ clss_of_state (Liminf_state Sts)" by simp then have "C \ grounding_of_state (Liminf_state Sts)" unfolding grounding_of_clss_def grounding_of_cls_def using D'_p by auto then show "C \ grounding_of_clss (Q_of_state (Liminf_state Sts))" using SQinf fair fair_state_seq_def by auto qed text \ The following corresponds to (one direction of) Theorem 4.13: \ -lemma ground_subclauses: - assumes - "\i < length CAs. CAs ! i = Cs ! i + poss (AAs ! i)" and - "length Cs = length CAs" and - "is_ground_cls_list CAs" - shows "is_ground_cls_list Cs" - unfolding is_ground_cls_list_def - by (metis assms in_set_conv_nth is_ground_cls_list_def is_ground_cls_union) - lemma subseteq_Liminf_state_eventually_always: fixes CC assumes "finite CC" and "CC \ {}" and "CC \ Q_of_state (Liminf_state Sts)" shows "\j. enat j < llength Sts \ (\j' \ enat j. j' < llength Sts \ CC \ Q_of_state (lnth Sts j'))" proof - from assms(3) have "\C \ CC. \j. enat j < llength Sts \ (\j' \ enat j. j' < llength Sts \ C \ Q_of_state (lnth Sts j'))" unfolding Liminf_state_def Liminf_llist_def by force then obtain f where f_p: "\C \ CC. f C < llength Sts \ (\j' \ enat (f C). j' < llength Sts \ C \ Q_of_state (lnth Sts j'))" by moura define j :: nat where "j = Max (f ` CC)" have "enat j < llength Sts" unfolding j_def using f_p assms(1) by (metis (mono_tags) Max_in assms(2) finite_imageI imageE image_is_empty) moreover have "\C j'. C \ CC \ enat j \ j' \ j' < llength Sts \ C \ Q_of_state (lnth Sts j')" proof (intro allI impI) fix C :: "'a clause" and j' :: nat assume a: "C \ CC" "enat j \ enat j'" "enat j' < llength Sts" then have "f C \ j'" unfolding j_def using assms(1) Max.bounded_iff by auto then show "C \ Q_of_state (lnth Sts j')" using f_p a by auto qed ultimately show ?thesis by auto qed lemma empty_clause_in_Q_of_Liminf_state: assumes deriv: "chain (\) Sts" and fair: "fair_state_seq Sts" and empty_in: "{#} \ Liminf_llist (lmap grounding_of_state Sts)" shows "{#} \ Q_of_state (Liminf_state Sts)" proof - define Gs :: "'a clause set llist" where ns: "Gs = lmap grounding_of_state Sts" from empty_in have in_Liminf_not_Rf: "{#} \ Liminf_llist Gs - sr.Rf (Liminf_llist Gs)" unfolding ns sr.Rf_def by auto then have "{#} \ grounding_of_clss (Q_of_state (Liminf_state Sts))" using fair_imp_Liminf_minus_Rf_subset_ground_Liminf_state[OF deriv fair ns] by auto then show ?thesis unfolding grounding_of_clss_def grounding_of_cls_def by auto qed lemma grounding_of_state_Liminf_state_subseteq: "grounding_of_state (Liminf_state Sts) \ Liminf_llist (lmap grounding_of_state Sts)" proof fix C :: "'a clause" assume "C \ grounding_of_state (Liminf_state Sts)" then obtain D \ where D_\_p: "D \ clss_of_state (Liminf_state Sts)" "D \ \ = C" "is_ground_subst \" unfolding grounding_of_clss_def grounding_of_cls_def by auto then have ii: "D \ Liminf_llist (lmap N_of_state Sts) \ D \ Liminf_llist (lmap P_of_state Sts) \ D \ Liminf_llist (lmap Q_of_state Sts)" unfolding Liminf_state_def by simp then have "C \ Liminf_llist (lmap grounding_of_clss (lmap N_of_state Sts)) \ C \ Liminf_llist (lmap grounding_of_clss (lmap P_of_state Sts)) \ C \ Liminf_llist (lmap grounding_of_clss (lmap Q_of_state Sts))" unfolding Liminf_llist_def grounding_of_clss_def grounding_of_cls_def + using D_\_p apply - apply (erule disjE) subgoal apply (rule disjI1) using D_\_p by auto subgoal - apply (erule HOL.disjE) + apply (erule disjE) subgoal apply (rule disjI2) apply (rule disjI1) using D_\_p by auto subgoal apply (rule disjI2) apply (rule disjI2) using D_\_p by auto done done then show "C \ Liminf_llist (lmap grounding_of_state Sts)" unfolding Liminf_llist_def grounding_of_clss_def by auto qed theorem RP_sound: assumes deriv: "chain (\) Sts" and "{#} \ clss_of_state (Liminf_state Sts)" shows "\ satisfiable (grounding_of_state (lhd Sts))" proof - from assms have "{#} \ grounding_of_state (Liminf_state Sts)" unfolding grounding_of_clss_def by (force intro: ex_ground_subst) then have "{#} \ Liminf_llist (lmap grounding_of_state Sts)" using grounding_of_state_Liminf_state_subseteq by auto then have "\ satisfiable (Liminf_llist (lmap grounding_of_state Sts))" using true_clss_def by auto then have "\ satisfiable (lhd (lmap grounding_of_state Sts))" using sr_ext.sat_limit_iff ground_derive_chain deriv by blast then show ?thesis using chain_not_lnull deriv by fastforce qed theorem RP_saturated_if_fair: assumes deriv: "chain (\) Sts" and fair: "fair_state_seq Sts" and empty_Q0: "Q_of_state (lhd Sts) = {}" shows "sr.saturated_upto (Liminf_llist (lmap grounding_of_state Sts))" proof - define Gs :: "'a clause set llist" where ns: "Gs = lmap grounding_of_state Sts" let ?N = "\i. grounding_of_state (lnth Sts i)" let ?Ns = "\i. N_of_state (lnth Sts i)" let ?Ps = "\i. P_of_state (lnth Sts i)" let ?Qs = "\i. Q_of_state (lnth Sts i)" have ground_ns_in_ground_limit_st: "Liminf_llist Gs - sr.Rf (Liminf_llist Gs) \ grounding_of_clss (Q_of_state (Liminf_state Sts))" using fair deriv fair_imp_Liminf_minus_Rf_subset_ground_Liminf_state ns by blast have derivns: "chain sr_ext.derive Gs" using ground_derive_chain deriv ns by auto { fix \ :: "'a inference" assume \_p: "\ \ gr.ord_\" let ?CC = "side_prems_of \" let ?DA = "main_prem_of \" let ?E = "concl_of \" assume a: "set_mset ?CC \ {?DA} \ Liminf_llist (lmap grounding_of_state Sts) - sr.Rf (Liminf_llist (lmap grounding_of_state Sts))" have ground_ground_Liminf: "is_ground_clss (Liminf_llist (lmap grounding_of_state Sts))" using Liminf_grounding_of_state_ground unfolding is_ground_clss_def by auto have ground_cc: "is_ground_clss (set_mset ?CC)" using a ground_ground_Liminf is_ground_clss_def by auto have ground_da: "is_ground_cls ?DA" using a grounding_ground singletonI ground_ground_Liminf by (simp add: Liminf_grounding_of_state_ground) from \_p obtain CAs AAs As where CAs_p: "gr.ord_resolve CAs ?DA AAs As ?E \ mset CAs = ?CC" unfolding gr.ord_\_def by auto have DA_CAs_in_ground_Liminf: "{?DA} \ set CAs \ grounding_of_clss (Q_of_state (Liminf_state Sts))" using a CAs_p fair unfolding fair_state_seq_def by (metis (no_types, lifting) Un_empty_left ground_ns_in_ground_limit_st a ns set_mset_mset subset_trans sup_commute) then have ground_cas: "is_ground_cls_list CAs" using CAs_p unfolding is_ground_cls_list_def by auto have "\\. ord_resolve S_Q CAs ?DA AAs As \ ?E" by (rule ground_ord_resolve_imp_ord_resolve[OF ground_da ground_cas gr.ground_resolution_with_selection_axioms CAs_p[THEN conjunct1]]) then obtain \ where \_p: "ord_resolve S_Q CAs ?DA AAs As \ ?E" by auto then obtain \s' \' \2' CAs' DA' AAs' As' \' E' where s_p: "is_ground_subst \'" "is_ground_subst_list \s'" "is_ground_subst \2'" "ord_resolve_rename S CAs' DA' AAs' As' \' E'" "CAs' \\cl \s' = CAs" "DA' \ \' = ?DA" "E' \ \2' = ?E" "{DA'} \ set CAs' \ Q_of_state (Liminf_state Sts)" using ord_resolve_rename_lifting[OF sel_stable, of "Q_of_state (Liminf_state Sts)" CAs ?DA] \_p[unfolded S_Q_def] selection_axioms DA_CAs_in_ground_Liminf by metis from this(8) have "\j. enat j < llength Sts \ (set CAs' \ {DA'} \ ?Qs j)" unfolding Liminf_llist_def using subseteq_Liminf_state_eventually_always[of "{DA'} \ set CAs'"] by auto then obtain j where j_p: "is_least (\j. enat j < llength Sts \ set CAs' \ {DA'} \ ?Qs j) j" using least_exists[of "\j. enat j < llength Sts \ set CAs' \ {DA'} \ ?Qs j"] by force then have j_p': "enat j < llength Sts" "set CAs' \ {DA'} \ ?Qs j" unfolding is_least_def by auto then have jn0: "j \ 0" using empty_Q0 by (metis bot_eq_sup_iff gr_implies_not_zero insert_not_empty llength_lnull lnth_0_conv_lhd sup.orderE) then have j_adds_CAs': "\ set CAs' \ {DA'} \ ?Qs (j - 1)" "set CAs' \ {DA'} \ ?Qs j" using j_p unfolding is_least_def apply (metis (no_types) One_nat_def Suc_diff_Suc Suc_ile_eq diff_diff_cancel diff_zero less_imp_le less_one neq0_conv zero_less_diff) using j_p'(2) by blast have "lnth Sts (j - 1) \ lnth Sts j" using j_p'(1) jn0 deriv chain_lnth_rel[of _ _ "j - 1"] by force then obtain C' where C'_p: "?Ns (j - 1) = {}" "?Ps (j - 1) = ?Ps j \ {C'}" "?Qs j = ?Qs (j - 1) \ {C'}" "?Ns j = concls_of (ord_FO_resolution.inferences_between (?Qs (j - 1)) C')" "C' \ set CAs' \ {DA'}" "C' \ ?Qs (j - 1)" using j_adds_CAs' by (induction rule: RP.cases) auto have "E' \ ?Ns j" proof - have "E' \ concls_of (ord_FO_resolution.inferences_between (Q_of_state (lnth Sts (j - 1))) C')" unfolding infer_from_def ord_FO_\_def inference_system.inferences_between_def apply (rule_tac x = "Infer (mset CAs') DA' E'" in image_eqI) subgoal by auto subgoal unfolding infer_from_def by (rule ord_resolve_rename.cases[OF s_p(4)]) (use s_p(4) C'_p(3,5) j_p'(2) in force) done then show ?thesis using C'_p(4) by auto qed then have "E' \ clss_of_state (lnth Sts j)" using j_p' by auto then have "?E \ grounding_of_state (lnth Sts j)" using s_p(7) s_p(3) unfolding grounding_of_clss_def grounding_of_cls_def by force then have "\ \ sr.Ri (grounding_of_state (lnth Sts j))" using sr.Ri_effective \_p by auto then have "\ \ sr_ext_Ri (?N j)" unfolding sr_ext_Ri_def by auto then have "\ \ sr_ext_Ri (Sup_llist (lmap grounding_of_state Sts))" using j_p' contra_subsetD llength_lmap lnth_lmap lnth_subset_Sup_llist sr_ext.Ri_mono by smt then have "\ \ sr_ext_Ri (Liminf_llist (lmap grounding_of_state Sts))" using sr_ext.Ri_limit_Sup[of Gs] derivns ns by blast } then have "sr_ext.saturated_upto (Liminf_llist (lmap grounding_of_state Sts))" unfolding sr_ext.saturated_upto_def sr_ext.inferences_from_def infer_from_def sr_ext_Ri_def by auto then show ?thesis using gd_ord_\_ngd_ord_\ sr.redundancy_criterion_axioms redundancy_criterion_standard_extension_saturated_upto_iff[of gr.ord_\] unfolding sr_ext_Ri_def by auto qed corollary RP_complete_if_fair: assumes deriv: "chain (\) Sts" and fair: "fair_state_seq Sts" and empty_Q0: "Q_of_state (lhd Sts) = {}" and unsat: "\ satisfiable (grounding_of_state (lhd Sts))" shows "{#} \ Q_of_state (Liminf_state Sts)" proof - have "\ satisfiable (Liminf_llist (lmap grounding_of_state Sts))" using unsat sr_ext.sat_limit_iff[OF ground_derive_chain] chain_not_lnull deriv by fastforce moreover have "sr.saturated_upto (Liminf_llist (lmap grounding_of_state Sts))" by (rule RP_saturated_if_fair[OF deriv fair empty_Q0, simplified]) ultimately have "{#} \ Liminf_llist (lmap grounding_of_state Sts)" using sr.saturated_upto_complete_if by auto then show ?thesis using empty_clause_in_Q_of_Liminf_state[OF deriv fair] by auto qed end end end diff --git a/thys/Ordered_Resolution_Prover/Lazy_List_Liminf.thy b/thys/Ordered_Resolution_Prover/Lazy_List_Liminf.thy --- a/thys/Ordered_Resolution_Prover/Lazy_List_Liminf.thy +++ b/thys/Ordered_Resolution_Prover/Lazy_List_Liminf.thy @@ -1,215 +1,218 @@ (* Title: Liminf of Lazy Lists Author: Jasmin Blanchette , 2014, 2017 Author: Dmitriy Traytel , 2014 Maintainer: Jasmin Blanchette *) section \Liminf of Lazy Lists\ theory Lazy_List_Liminf imports Coinductive.Coinductive_List begin text \ Lazy lists, as defined in the \emph{Archive of Formal Proofs}, provide finite and infinite lists in one type, defined coinductively. The present theory introduces the concept of the union of all elements of a lazy list of sets and the limit of such a lazy list. The definitions are stated more generally in terms of lattices. The basis for this theory is Section 4.1 (``Theorem Proving Processes'') of Bachmair and Ganzinger's chapter. \ definition Sup_llist :: "'a set llist \ 'a set" where "Sup_llist Xs = (\i \ {i. enat i < llength Xs}. lnth Xs i)" -lemma lnth_subset_Sup_llist: "enat i < llength xs \ lnth xs i \ Sup_llist xs" +lemma lnth_subset_Sup_llist: "enat i < llength Xs \ lnth Xs i \ Sup_llist Xs" + unfolding Sup_llist_def by auto + +lemma Sup_llist_imp_exists_index: "x \ Sup_llist Xs \ \i. enat i < llength Xs \ x \ lnth Xs i" unfolding Sup_llist_def by auto lemma Sup_llist_LNil[simp]: "Sup_llist LNil = {}" unfolding Sup_llist_def by auto lemma Sup_llist_LCons[simp]: "Sup_llist (LCons X Xs) = X \ Sup_llist Xs" unfolding Sup_llist_def proof (intro subset_antisym subsetI) fix x assume "x \ (\i \ {i. enat i < llength (LCons X Xs)}. lnth (LCons X Xs) i)" then obtain i where len: "enat i < llength (LCons X Xs)" and nth: "x \ lnth (LCons X Xs) i" by blast from nth have "x \ X \ i > 0 \ x \ lnth Xs (i - 1)" by (metis lnth_LCons' neq0_conv) then have "x \ X \ (\i. enat i < llength Xs \ x \ lnth Xs i)" by (metis len Suc_pred' eSuc_enat iless_Suc_eq less_irrefl llength_LCons not_less order_trans) then show "x \ X \ (\i \ {i. enat i < llength Xs}. lnth Xs i)" by blast qed ((auto)[], metis i0_lb lnth_0 zero_enat_def, metis Suc_ile_eq lnth_Suc_LCons) lemma lhd_subset_Sup_llist: "\ lnull Xs \ lhd Xs \ Sup_llist Xs" by (cases Xs) simp_all definition Sup_upto_llist :: "'a set llist \ nat \ 'a set" where "Sup_upto_llist Xs j = (\i \ {i. enat i < llength Xs \ i \ j}. lnth Xs i)" lemma Sup_upto_llist_0[simp]: "Sup_upto_llist Xs 0 = (if 0 < llength Xs then lnth Xs 0 else {})" unfolding Sup_upto_llist_def image_def by (simp add: enat_0) lemma Sup_upto_llist_Suc[simp]: "Sup_upto_llist Xs (Suc j) = Sup_upto_llist Xs j \ (if enat (Suc j) < llength Xs then lnth Xs (Suc j) else {})" unfolding Sup_upto_llist_def image_def by (auto intro: le_SucI elim: le_SucE) lemma Sup_upto_llist_mono: "j \ k \ Sup_upto_llist Xs j \ Sup_upto_llist Xs k" unfolding Sup_upto_llist_def by auto lemma Sup_upto_llist_subset_Sup_llist: "j \ k \ Sup_upto_llist Xs j \ Sup_llist Xs" unfolding Sup_llist_def Sup_upto_llist_def by auto lemma elem_Sup_llist_imp_Sup_upto_llist: "x \ Sup_llist Xs \ \j < llength Xs. x \ Sup_upto_llist Xs j" unfolding Sup_llist_def Sup_upto_llist_def by blast lemma lnth_subset_Sup_upto_llist: "enat j < llength Xs \ lnth Xs j \ Sup_upto_llist Xs j" unfolding Sup_upto_llist_def by auto lemma finite_Sup_llist_imp_Sup_upto_llist: assumes "finite X" and "X \ Sup_llist Xs" shows "\k. X \ Sup_upto_llist Xs k" using assms proof induct case (insert x X) then have x: "x \ Sup_llist Xs" and X: "X \ Sup_llist Xs" by simp+ from x obtain k where k: "x \ Sup_upto_llist Xs k" using elem_Sup_llist_imp_Sup_upto_llist by fast from X obtain k' where k': "X \ Sup_upto_llist Xs k'" using insert.hyps(3) by fast have "insert x X \ Sup_upto_llist Xs (max k k')" using k k' by (metis insert_absorb insert_subset Sup_upto_llist_mono max.cobounded2 max.commute order.trans) then show ?case by fast qed simp definition Liminf_llist :: "'a set llist \ 'a set" where "Liminf_llist Xs = (\i \ {i. enat i < llength Xs}. \j \ {j. i \ j \ enat j < llength Xs}. lnth Xs j)" lemma Liminf_llist_LNil[simp]: "Liminf_llist LNil = {}" unfolding Liminf_llist_def by simp lemma Liminf_llist_LCons: "Liminf_llist (LCons X Xs) = (if lnull Xs then X else Liminf_llist Xs)" (is "?lhs = ?rhs") proof (cases "lnull Xs") case nnull: False show ?thesis proof { fix x assume "\i. enat i \ llength Xs \ (\j. i \ j \ enat j \ llength Xs \ x \ lnth (LCons X Xs) j)" then have "\i. enat (Suc i) \ llength Xs \ (\j. Suc i \ j \ enat j \ llength Xs \ x \ lnth (LCons X Xs) j)" by (cases "llength Xs", metis not_lnull_conv[THEN iffD1, OF nnull] Suc_le_D eSuc_enat eSuc_ile_mono llength_LCons not_less_eq_eq zero_enat_def zero_le, metis Suc_leD enat_ord_code(3)) then have "\i. enat i < llength Xs \ (\j. i \ j \ enat j < llength Xs \ x \ lnth Xs j)" by (metis Suc_ile_eq Suc_n_not_le_n lift_Suc_mono_le lnth_Suc_LCons nat_le_linear) } then show "?lhs \ ?rhs" by (simp add: Liminf_llist_def nnull) (rule subsetI, simp) { fix x assume "\i. enat i < llength Xs \ (\j. i \ j \ enat j < llength Xs \ x \ lnth Xs j)" then obtain i where i: "enat i < llength Xs" and j: "\j. i \ j \ enat j < llength Xs \ x \ lnth Xs j" by blast have "enat (Suc i) \ llength Xs" using i by (simp add: Suc_ile_eq) moreover have "\j. Suc i \ j \ enat j \ llength Xs \ x \ lnth (LCons X Xs) j" using Suc_ile_eq Suc_le_D j by force ultimately have "\i. enat i \ llength Xs \ (\j. i \ j \ enat j \ llength Xs \ x \ lnth (LCons X Xs) j)" by blast } then show "?rhs \ ?lhs" by (simp add: Liminf_llist_def nnull) (rule subsetI, simp) qed qed (simp add: Liminf_llist_def enat_0_iff(1)) lemma lfinite_Liminf_llist: "lfinite Xs \ Liminf_llist Xs = (if lnull Xs then {} else llast Xs)" proof (induction rule: lfinite_induct) case (LCons xs) then obtain y ys where xs: "xs = LCons y ys" by (meson not_lnull_conv) show ?case unfolding xs by (simp add: Liminf_llist_LCons LCons.IH[unfolded xs, simplified] llast_LCons) qed (simp add: Liminf_llist_def) lemma Liminf_llist_ltl: "\ lnull (ltl Xs) \ Liminf_llist Xs = Liminf_llist (ltl Xs)" by (metis Liminf_llist_LCons lhd_LCons_ltl lnull_ltlI) lemma Liminf_llist_subset_Sup_llist: "Liminf_llist Xs \ Sup_llist Xs" unfolding Liminf_llist_def Sup_llist_def by fast lemma image_Liminf_llist_subset: "f ` Liminf_llist Ns \ Liminf_llist (lmap ((`) f) Ns)" unfolding Liminf_llist_def by auto lemma Liminf_llist_imp_exists_index: "x \ Liminf_llist Xs \ \i. enat i < llength Xs \ x \ lnth Xs i" unfolding Liminf_llist_def by auto lemma Liminf_llist_lmap_image: assumes f_inj: "inj_on f (Sup_llist (lmap g xs))" shows "Liminf_llist (lmap (\x. f ` g x) xs) = f ` Liminf_llist (lmap g xs)" (is "?lhs = ?rhs") proof show "?lhs \ ?rhs" proof fix x assume "x \ Liminf_llist (lmap (\x. f ` g x) xs)" then obtain i where i_lt: "enat i < llength xs" and x_in_fgj: "\j. i \ j \ enat j < llength xs \ x \ f ` g (lnth xs j)" unfolding Liminf_llist_def by auto have ex_in_gi: "\y. y \ g (lnth xs i) \ x = f y" using f_inj i_lt x_in_fgj unfolding inj_on_def Sup_llist_def by auto have "\y. \j. i \ j \ enat j < llength xs \ y \ g (lnth xs j) \ x = f y" apply (rule exI[of _ "SOME y. y \ g (lnth xs i) \ x = f y"]) using someI_ex[OF ex_in_gi] x_in_fgj f_inj i_lt x_in_fgj unfolding inj_on_def Sup_llist_def by simp (metis (no_types, lifting) imageE) then show "x \ f ` Liminf_llist (lmap g xs)" using i_lt unfolding Liminf_llist_def by auto qed next show "?rhs \ ?lhs" using image_Liminf_llist_subset[of f "lmap g xs", unfolded llist.map_comp] by auto qed lemma Liminf_llist_lmap_union: assumes "\x \ lset xs. \Y \ lset xs. g x \ h Y = {}" shows "Liminf_llist (lmap (\x. g x \ h x) xs) = Liminf_llist (lmap g xs) \ Liminf_llist (lmap h xs)" (is "?lhs = ?rhs") proof (intro equalityI subsetI) fix x assume x_in: "x \ ?lhs" then obtain i where i_lt: "enat i < llength xs" and j: "\j. i \ j \ enat j < llength xs \ x \ g (lnth xs j) \ x \ h (lnth xs j)" using x_in[unfolded Liminf_llist_def, simplified] by blast then have "(\i'. enat i' < llength xs \ (\j. i' \ j \ enat j < llength xs \ x \ g (lnth xs j))) \ (\i'. enat i' < llength xs \ (\j. i' \ j \ enat j < llength xs \ x \ h (lnth xs j)))" using assms[unfolded disjoint_iff_not_equal] by (metis in_lset_conv_lnth) then show "x \ ?rhs" unfolding Liminf_llist_def by simp next fix x show "x \ ?rhs \ x \ ?lhs" using assms unfolding Liminf_llist_def by auto qed end