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,1267 +1,1270 @@ (* Title: Abstract Substitutions Author: Dmitriy Traytel , 2014 Author: Jasmin Blanchette , 2014, 2017 Author: Anders Schlichtkrull , 2016, 2017 Maintainer: Anders Schlichtkrull *) section \Abstract Substitutions\ theory Abstract_Substitution imports Clausal_Logic Map2 begin text \ Atoms and substitutions are abstracted away behind some locales, to avoid having a direct dependency on the IsaFoR library. Conventions: \'s\ substitutions, \'a\ atoms. \ subsection \Library\ lemma f_Suc_decr_eventually_const: fixes f :: "nat \ nat" assumes leq: "\i. f (Suc i) \ f i" shows "\l. \l' \ l. f l' = f (Suc l')" proof (rule ccontr) assume a: "\l. \l' \ l. f l' = f (Suc l')" have "\i. \i'. i' > i \ f i' < f i" proof fix i from a have "\l' \ i. f l' \ f (Suc l')" by auto then obtain l' where l'_p: "l' \ i \ f l' \ f (Suc l')" by metis then have "f l' > f (Suc l')" using leq le_eq_less_or_eq by auto moreover have "f i \ f l'" using leq l'_p by (induction l' arbitrary: i) (blast intro: lift_Suc_antimono_le)+ ultimately show "\i' > i. f i' < f i" using l'_p less_le_trans by blast qed then obtain g_sm :: "nat \ nat" where g_sm_p: "\i. g_sm i > i \ f (g_sm i) < f i" by metis define c :: "nat \ nat" where "\n. c n = (g_sm ^^ n) 0" have "f (c i) > f (c (Suc i))" for i by (induction i) (auto simp: c_def g_sm_p) then have "\i. (f \ c) i > (f \ c) (Suc i)" by auto then have "\fc :: nat \ nat. \i. fc i > fc (Suc i)" by metis then show False using wf_less_than by (simp add: wf_iff_no_infinite_down_chain) qed subsection \Substitution Operators\ locale substitution_ops = fixes subst_atm :: "'a \ 's \ 'a" and id_subst :: 's and comp_subst :: "'s \ 's \ 's" begin abbreviation subst_atm_abbrev :: "'a \ 's \ 'a" (infixl "\a" 67) where "subst_atm_abbrev \ subst_atm" abbreviation comp_subst_abbrev :: "'s \ 's \ 's" (infixl "\" 67) where "comp_subst_abbrev \ comp_subst" definition comp_substs :: "'s list \ 's list \ 's list" (infixl "\s" 67) where "\s \s \s = map2 comp_subst \s \s" definition subst_atms :: "'a set \ 's \ 'a set" (infixl "\as" 67) where "AA \as \ = (\A. A \a \) ` AA" definition subst_atmss :: "'a set set \ 's \ 'a set set" (infixl "\ass" 67) where "AAA \ass \ = (\AA. AA \as \) ` AAA" definition subst_atm_list :: "'a list \ 's \ 'a list" (infixl "\al" 67) where "As \al \ = map (\A. A \a \) As" definition subst_atm_mset :: "'a multiset \ 's \ 'a multiset" (infixl "\am" 67) where "AA \am \ = image_mset (\A. A \a \) AA" definition subst_atm_mset_list :: "'a multiset list \ 's \ 'a multiset list" (infixl "\aml" 67) where "AAA \aml \ = map (\AA. AA \am \) AAA" definition subst_atm_mset_lists :: "'a multiset list \ 's list \ 'a multiset list" (infixl "\\aml" 67) where "AAs \\aml \s = map2 (\am) AAs \s" definition subst_lit :: "'a literal \ 's \ 'a literal" (infixl "\l" 67) where "L \l \ = map_literal (\A. A \a \) L" lemma atm_of_subst_lit[simp]: "atm_of (L \l \) = atm_of L \a \" unfolding subst_lit_def by (cases L) simp+ definition subst_cls :: "'a clause \ 's \ 'a clause" (infixl "\" 67) where "AA \ \ = image_mset (\A. A \l \) AA" definition subst_clss :: "'a clause set \ 's \ 'a clause set" (infixl "\cs" 67) where "AA \cs \ = (\A. A \ \) ` AA" definition subst_cls_list :: "'a clause list \ 's \ 'a clause list" (infixl "\cl" 67) where "Cs \cl \ = map (\A. A \ \) Cs" definition subst_cls_lists :: "'a clause list \ 's list \ 'a clause list" (infixl "\\cl" 67) where "Cs \\cl \s = map2 (\) Cs \s" definition subst_cls_mset :: "'a clause multiset \ 's \ 'a clause multiset" (infixl "\cm" 67) where "CC \cm \ = image_mset (\A. A \ \) CC" lemma subst_cls_add_mset[simp]: "add_mset L C \ \ = add_mset (L \l \) (C \ \)" unfolding subst_cls_def by simp lemma subst_cls_mset_add_mset[simp]: "add_mset C CC \cm \ = add_mset (C \ \) (CC \cm \)" unfolding subst_cls_mset_def by simp definition generalizes_atm :: "'a \ 'a \ bool" where "generalizes_atm A B \ (\\. A \a \ = B)" definition strictly_generalizes_atm :: "'a \ 'a \ bool" where "strictly_generalizes_atm A B \ generalizes_atm A B \ \ generalizes_atm B A" definition generalizes_lit :: "'a literal \ 'a literal \ bool" where "generalizes_lit L M \ (\\. L \l \ = M)" definition strictly_generalizes_lit :: "'a literal \ 'a literal \ bool" where "strictly_generalizes_lit L M \ generalizes_lit L M \ \ generalizes_lit M L" definition generalizes :: "'a clause \ 'a clause \ bool" where "generalizes C D \ (\\. C \ \ = D)" definition strictly_generalizes :: "'a clause \ 'a clause \ bool" where "strictly_generalizes C D \ generalizes C D \ \ generalizes D C" definition subsumes :: "'a clause \ 'a clause \ bool" where "subsumes C D \ (\\. C \ \ \# D)" definition strictly_subsumes :: "'a clause \ 'a clause \ bool" where "strictly_subsumes C D \ subsumes C D \ \ subsumes D C" definition variants :: "'a clause \ 'a clause \ bool" where "variants C D \ generalizes C D \ generalizes D C" definition is_renaming :: "'s \ bool" where "is_renaming \ \ (\\. \ \ \ = id_subst)" definition is_renaming_list :: "'s list \ bool" where "is_renaming_list \s \ (\\ \ set \s. is_renaming \)" definition inv_renaming :: "'s \ 's" where "inv_renaming \ = (SOME \. \ \ \ = id_subst)" definition is_ground_atm :: "'a \ bool" where "is_ground_atm A \ (\\. A = A \a \)" definition is_ground_atms :: "'a set \ bool" where "is_ground_atms AA = (\A \ AA. is_ground_atm A)" definition is_ground_atm_list :: "'a list \ bool" where "is_ground_atm_list As \ (\A \ set As. is_ground_atm A)" definition is_ground_atm_mset :: "'a multiset \ bool" where "is_ground_atm_mset AA \ (\A. A \# AA \ is_ground_atm A)" definition is_ground_lit :: "'a literal \ bool" where "is_ground_lit L \ is_ground_atm (atm_of L)" definition is_ground_cls :: "'a clause \ bool" where "is_ground_cls C \ (\L. L \# C \ is_ground_lit L)" definition is_ground_clss :: "'a clause set \ bool" where "is_ground_clss CC \ (\C \ CC. is_ground_cls C)" definition is_ground_cls_list :: "'a clause list \ bool" where "is_ground_cls_list CC \ (\C \ set CC. is_ground_cls C)" definition is_ground_subst :: "'s \ bool" where "is_ground_subst \ \ (\A. is_ground_atm (A \a \))" definition is_ground_subst_list :: "'s list \ bool" where "is_ground_subst_list \s \ (\\ \ set \s. is_ground_subst \)" definition grounding_of_cls :: "'a clause \ 'a clause set" where "grounding_of_cls C = {C \ \ |\. is_ground_subst \}" definition grounding_of_clss :: "'a clause set \ 'a clause set" where "grounding_of_clss CC = (\C \ CC. grounding_of_cls C)" definition is_unifier :: "'s \ 'a set \ bool" where "is_unifier \ AA \ card (AA \as \) \ 1" definition is_unifiers :: "'s \ 'a set set \ bool" where "is_unifiers \ AAA \ (\AA \ AAA. is_unifier \ AA)" definition is_mgu :: "'s \ 'a set set \ bool" where "is_mgu \ AAA \ is_unifiers \ AAA \ (\\. is_unifiers \ AAA \ (\\. \ = \ \ \))" definition var_disjoint :: "'a clause list \ bool" where "var_disjoint Cs \ (\\s. length \s = length Cs \ (\\. \i < length Cs. \S. S \# Cs ! i \ S \ \s ! i = S \ \))" end subsection \Substitution Lemmas\ locale substitution = substitution_ops subst_atm id_subst comp_subst for subst_atm :: "'a \ 's \ 'a" and id_subst :: 's and comp_subst :: "'s \ 's \ 's" + fixes renamings_apart :: "'a clause list \ 's list" and atm_of_atms :: "'a list \ 'a" assumes subst_atm_id_subst[simp]: "A \a id_subst = A" and subst_atm_comp_subst[simp]: "A \a (\ \ \) = (A \a \) \a \" and subst_ext: "(\A. A \a \ = A \a \) \ \ = \" and make_ground_subst: "is_ground_cls (C \ \) \ \\. is_ground_subst \ \C \ \ = C \ \" and wf_strictly_generalizes_atm: "wfP strictly_generalizes_atm" and renamings_apart_length: "length (renamings_apart Cs) = length Cs" and renamings_apart_renaming: "\ \ set (renamings_apart Cs) \ is_renaming \" and renamings_apart_var_disjoint: "var_disjoint (Cs \\cl (renamings_apart Cs))" and atm_of_atms_subst: "\As Bs. atm_of_atms As \a \ = atm_of_atms Bs \ map (\A. A \a \) As = Bs" begin lemma subst_ext_iff: "\ = \ \ (\A. A \a \ = A \a \)" by (blast intro: subst_ext) subsubsection \Identity Substitution\ lemma id_subst_comp_subst[simp]: "id_subst \ \ = \" by (rule subst_ext) simp lemma comp_subst_id_subst[simp]: "\ \ id_subst = \" by (rule subst_ext) simp lemma id_subst_comp_substs[simp]: "replicate (length \s) id_subst \s \s = \s" using comp_substs_def by (induction \s) auto lemma comp_substs_id_subst[simp]: "\s \s replicate (length \s) id_subst = \s" using comp_substs_def by (induction \s) auto lemma subst_atms_id_subst[simp]: "AA \as id_subst = AA" unfolding subst_atms_def by simp lemma subst_atmss_id_subst[simp]: "AAA \ass id_subst = AAA" unfolding subst_atmss_def by simp lemma subst_atm_list_id_subst[simp]: "As \al id_subst = As" unfolding subst_atm_list_def by auto lemma subst_atm_mset_id_subst[simp]: "AA \am id_subst = AA" unfolding subst_atm_mset_def by simp lemma subst_atm_mset_list_id_subst[simp]: "AAs \aml id_subst = AAs" unfolding subst_atm_mset_list_def by simp lemma subst_atm_mset_lists_id_subst[simp]: "AAs \\aml replicate (length AAs) id_subst = AAs" unfolding subst_atm_mset_lists_def by (induct AAs) auto lemma subst_lit_id_subst[simp]: "L \l id_subst = L" unfolding subst_lit_def by (simp add: literal.map_ident) lemma subst_cls_id_subst[simp]: "C \ id_subst = C" unfolding subst_cls_def by simp lemma subst_clss_id_subst[simp]: "CC \cs id_subst = CC" unfolding subst_clss_def by simp lemma subst_cls_list_id_subst[simp]: "Cs \cl id_subst = Cs" unfolding subst_cls_list_def by simp lemma subst_cls_lists_id_subst[simp]: "Cs \\cl replicate (length Cs) id_subst = Cs" unfolding subst_cls_lists_def by (induct Cs) auto lemma subst_cls_mset_id_subst[simp]: "CC \cm id_subst = CC" unfolding subst_cls_mset_def by simp subsubsection \Associativity of Composition\ lemma comp_subst_assoc[simp]: "\ \ (\ \ \) = \ \ \ \ \" by (rule subst_ext) simp subsubsection \Compatibility of Substitution and Composition\ lemma subst_atms_comp_subst[simp]: "AA \as (\ \ \) = AA \as \ \as \" unfolding subst_atms_def by auto lemma subst_atmss_comp_subst[simp]: "AAA \ass (\ \ \) = AAA \ass \ \ass \" unfolding subst_atmss_def by auto lemma subst_atm_list_comp_subst[simp]: "As \al (\ \ \) = As \al \ \al \" unfolding subst_atm_list_def by auto lemma subst_atm_mset_comp_subst[simp]: "AA \am (\ \ \) = AA \am \ \am \" unfolding subst_atm_mset_def by auto lemma subst_atm_mset_list_comp_subst[simp]: "AAs \aml (\ \ \) = (AAs \aml \) \aml \" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_comp_substs[simp]: "AAs \\aml (\s \s \s) = AAs \\aml \s \\aml \s" unfolding subst_atm_mset_lists_def comp_substs_def map_zip_map map_zip_map2 map_zip_assoc by (simp add: split_def) lemma subst_lit_comp_subst[simp]: "L \l (\ \ \) = L \l \ \l \" unfolding subst_lit_def by (auto simp: literal.map_comp o_def) lemma subst_cls_comp_subst[simp]: "C \ (\ \ \) = C \ \ \ \" unfolding subst_cls_def by auto lemma subst_clsscomp_subst[simp]: "CC \cs (\ \ \) = CC \cs \ \cs \" unfolding subst_clss_def by auto lemma subst_cls_list_comp_subst[simp]: "Cs \cl (\ \ \) = Cs \cl \ \cl \" unfolding subst_cls_list_def by auto lemma subst_cls_lists_comp_substs[simp]: "Cs \\cl (\s \s \s) = Cs \\cl \s \\cl \s" unfolding subst_cls_lists_def comp_substs_def map_zip_map map_zip_map2 map_zip_assoc by (simp add: split_def) lemma subst_cls_mset_comp_subst[simp]: "CC \cm (\ \ \) = CC \cm \ \cm \" unfolding subst_cls_mset_def by auto subsubsection \``Commutativity'' of Membership and Substitution\ lemma Melem_subst_atm_mset[simp]: "A \# AA \am \ \ (\B. B \# AA \ A = B \a \)" unfolding subst_atm_mset_def by auto lemma Melem_subst_cls[simp]: "L \# C \ \ \ (\M. M \# C \ L = M \l \)" unfolding subst_cls_def by auto lemma Melem_subst_cls_mset[simp]: "AA \# CC \cm \ \ (\BB. BB \# CC \ AA = BB \ \)" unfolding subst_cls_mset_def by auto subsubsection \Signs and Substitutions\ lemma subst_lit_is_neg[simp]: "is_neg (L \l \) = is_neg L" unfolding subst_lit_def by auto lemma subst_lit_is_pos[simp]: "is_pos (L \l \) = is_pos L" unfolding subst_lit_def by auto lemma subst_minus[simp]: "(- L) \l \ = - (L \l \)" by (simp add: literal.map_sel subst_lit_def uminus_literal_def) subsubsection \Substitution on Literal(s)\ lemma eql_neg_lit_eql_atm[simp]: "(Neg A' \l \) = Neg A \ A' \a \ = A" by (simp add: subst_lit_def) lemma eql_pos_lit_eql_atm[simp]: "(Pos A' \l \) = Pos A \ A' \a \ = A" by (simp add: subst_lit_def) lemma subst_cls_negs[simp]: "(negs AA) \ \ = negs (AA \am \)" unfolding subst_cls_def subst_lit_def subst_atm_mset_def by auto lemma subst_cls_poss[simp]: "(poss AA) \ \ = poss (AA \am \)" unfolding subst_cls_def subst_lit_def subst_atm_mset_def by auto lemma atms_of_subst_atms: "atms_of C \as \ = atms_of (C \ \)" proof - have "atms_of (C \ \) = set_mset (image_mset atm_of (image_mset (map_literal (\A. A \a \)) C))" unfolding subst_cls_def subst_atms_def subst_lit_def atms_of_def by auto also have "... = set_mset (image_mset (\A. A \a \) (image_mset atm_of C))" by simp (meson literal.map_sel) finally show "atms_of C \as \ = atms_of (C \ \)" unfolding subst_atms_def atms_of_def by auto qed lemma in_image_Neg_is_neg[simp]: "L \l \ \ Neg ` AA \ is_neg L" by (metis bex_imageD literal.disc(2) literal.map_disc_iff subst_lit_def) lemma subst_lit_in_negs_subst_is_neg: "L \l \ \# (negs AA) \ \ \ is_neg L" by simp lemma subst_lit_in_negs_is_neg: "L \l \ \# negs AA \ is_neg L" by simp subsubsection \Substitution on Empty\ lemma subst_atms_empty[simp]: "{} \as \ = {}" unfolding subst_atms_def by auto lemma subst_atmss_empty[simp]: "{} \ass \ = {}" unfolding subst_atmss_def by auto lemma comp_substs_empty_iff[simp]: "\s \s \s = [] \ \s = [] \ \s = []" using comp_substs_def map2_empty_iff by auto lemma subst_atm_list_empty[simp]: "[] \al \ = []" unfolding subst_atm_list_def by auto lemma subst_atm_mset_empty[simp]: "{#} \am \ = {#}" unfolding subst_atm_mset_def by auto lemma subst_atm_mset_list_empty[simp]: "[] \aml \ = []" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_empty[simp]: "[] \\aml \s = []" unfolding subst_atm_mset_lists_def by auto lemma subst_cls_empty[simp]: "{#} \ \ = {#}" unfolding subst_cls_def by auto lemma subst_clss_empty[simp]: "{} \cs \ = {}" unfolding subst_clss_def by auto lemma subst_cls_list_empty[simp]: "[] \cl \ = []" unfolding subst_cls_list_def by auto lemma subst_cls_lists_empty[simp]: "[] \\cl \s = []" unfolding subst_cls_lists_def by auto lemma subst_scls_mset_empty[simp]: "{#} \cm \ = {#}" unfolding subst_cls_mset_def by auto lemma subst_atms_empty_iff[simp]: "AA \as \ = {} \ AA = {}" unfolding subst_atms_def by auto lemma subst_atmss_empty_iff[simp]: "AAA \ass \ = {} \ AAA = {}" unfolding subst_atmss_def by auto lemma subst_atm_list_empty_iff[simp]: "As \al \ = [] \ As = []" unfolding subst_atm_list_def by auto lemma subst_atm_mset_empty_iff[simp]: "AA \am \ = {#} \ AA = {#}" unfolding subst_atm_mset_def by auto lemma subst_atm_mset_list_empty_iff[simp]: "AAs \aml \ = [] \ AAs = []" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_empty_iff[simp]: "AAs \\aml \s = [] \ (AAs = [] \ \s = [])" using map2_empty_iff subst_atm_mset_lists_def by auto lemma subst_cls_empty_iff[simp]: "C \ \ = {#} \ C = {#}" unfolding subst_cls_def by auto lemma subst_clss_empty_iff[simp]: "CC \cs \ = {} \ CC = {}" unfolding subst_clss_def by auto lemma subst_cls_list_empty_iff[simp]: "Cs \cl \ = [] \ Cs = []" unfolding subst_cls_list_def by auto lemma subst_cls_lists_empty_iff[simp]: "Cs \\cl \s = [] \ Cs = [] \ \s = []" using map2_empty_iff subst_cls_lists_def by auto lemma subst_cls_mset_empty_iff[simp]: "CC \cm \ = {#} \ CC = {#}" unfolding subst_cls_mset_def by auto subsubsection \Substitution on a Union\ lemma subst_atms_union[simp]: "(AA \ BB) \as \ = AA \as \ \ BB \as \" unfolding subst_atms_def by auto lemma subst_atmss_union[simp]: "(AAA \ BBB) \ass \ = AAA \ass \ \ BBB \ass \" unfolding subst_atmss_def by auto lemma subst_atm_list_append[simp]: "(As @ Bs) \al \ = As \al \ @ Bs \al \" unfolding subst_atm_list_def by auto lemma subst_atm_mset_union[simp]: "(AA + BB) \am \ = AA \am \ + BB \am \" unfolding subst_atm_mset_def by auto lemma subst_atm_mset_list_append[simp]: "(AAs @ BBs) \aml \ = AAs \aml \ @ BBs \aml \" unfolding subst_atm_mset_list_def by auto lemma subst_cls_union[simp]: "(C + D) \ \ = C \ \ + D \ \" unfolding subst_cls_def by auto lemma subst_clss_union[simp]: "(CC \ DD) \cs \ = CC \cs \ \ DD \cs \" unfolding subst_clss_def by auto lemma subst_cls_list_append[simp]: "(Cs @ Ds) \cl \ = Cs \cl \ @ Ds \cl \" unfolding subst_cls_list_def by auto lemma subst_cls_lists_append[simp]: "length Cs = length \s \ length Cs' = length \s' \ (Cs @ Cs') \\cl (\s @ \s') = Cs \\cl \s @ Cs' \\cl \s'" unfolding subst_cls_lists_def by auto lemma subst_cls_mset_union[simp]: "(CC + DD) \cm \ = CC \cm \ + DD \cm \" unfolding subst_cls_mset_def by auto subsubsection \Substitution on a Singleton\ lemma subst_atms_single[simp]: "{A} \as \ = {A \a \}" unfolding subst_atms_def by auto lemma subst_atmss_single[simp]: "{AA} \ass \ = {AA \as \}" unfolding subst_atmss_def by auto lemma subst_atm_list_single[simp]: "[A] \al \ = [A \a \]" unfolding subst_atm_list_def by auto lemma subst_atm_mset_single[simp]: "{#A#} \am \ = {#A \a \#}" unfolding subst_atm_mset_def by auto lemma subst_atm_mset_list[simp]: "[AA] \aml \ = [AA \am \]" unfolding subst_atm_mset_list_def by auto lemma subst_cls_single[simp]: "{#L#} \ \ = {#L \l \#}" by simp lemma subst_clss_single[simp]: "{C} \cs \ = {C \ \}" unfolding subst_clss_def by auto lemma subst_cls_list_single[simp]: "[C] \cl \ = [C \ \]" unfolding subst_cls_list_def by auto lemma subst_cls_lists_single[simp]: "[C] \\cl [\] = [C \ \]" unfolding subst_cls_lists_def by auto lemma subst_cls_mset_single[simp]: "{#C#} \cm \ = {#C \ \#}" by simp subsubsection \Substitution on @{term Cons}\ lemma subst_atm_list_Cons[simp]: "(A # As) \al \ = A \a \ # As \al \" unfolding subst_atm_list_def by auto lemma subst_atm_mset_list_Cons[simp]: "(A # As) \aml \ = A \am \ # As \aml \" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_Cons[simp]: "(C # Cs) \\aml (\ # \s) = C \am \ # Cs \\aml \s" unfolding subst_atm_mset_lists_def by auto lemma subst_cls_list_Cons[simp]: "(C # Cs) \cl \ = C \ \ # Cs \cl \" unfolding subst_cls_list_def by auto lemma subst_cls_lists_Cons[simp]: "(C # Cs) \\cl (\ # \s) = C \ \ # Cs \\cl \s" unfolding subst_cls_lists_def by auto subsubsection \Substitution on @{term tl}\ lemma subst_atm_list_tl[simp]: "tl (As \al \) = tl As \al \" by (cases As) auto lemma subst_atm_mset_list_tl[simp]: "tl (AAs \aml \) = tl AAs \aml \" by (cases AAs) auto lemma subst_cls_list_tl[simp]: "tl (Cs \cl \) = tl Cs \cl \" by (cases Cs) auto lemma subst_cls_lists_tl[simp]: "length Cs = length \s \ tl (Cs \\cl \s) = tl Cs \\cl tl \s" by (cases Cs; cases \s) auto subsubsection \Substitution on @{term nth}\ lemma comp_substs_nth[simp]: "length \s = length \s \ i < length \s \ (\s \s \s) ! i = (\s ! i) \ (\s ! i)" by (simp add: comp_substs_def) lemma subst_atm_list_nth[simp]: "i < length As \ (As \al \) ! i = As ! i \a \" unfolding subst_atm_list_def using less_Suc_eq_0_disj nth_map by force lemma subst_atm_mset_list_nth[simp]: "i < length AAs \ (AAs \aml \) ! i = (AAs ! i) \am \" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_nth[simp]: "length AAs = length \s \ i < length AAs \ (AAs \\aml \s) ! i = (AAs ! i) \am (\s ! i)" unfolding subst_atm_mset_lists_def by auto lemma subst_cls_list_nth[simp]: "i < length Cs \ (Cs \cl \) ! i = (Cs ! i) \ \" unfolding subst_cls_list_def using less_Suc_eq_0_disj nth_map by (induction Cs) auto lemma subst_cls_lists_nth[simp]: "length Cs = length \s \ i < length Cs \ (Cs \\cl \s) ! i = (Cs ! i) \ (\s ! i)" unfolding subst_cls_lists_def by auto subsubsection \Substitution on Various Other Functions\ lemma subst_clss_image[simp]: "image f X \cs \ = {f x \ \ | x. x \ X}" unfolding subst_clss_def by auto lemma subst_cls_mset_image_mset[simp]: "image_mset f X \cm \ = {# f x \ \. x \# X #}" unfolding subst_cls_mset_def by auto lemma mset_subst_atm_list_subst_atm_mset[simp]: "mset (As \al \) = mset (As) \am \" unfolding subst_atm_list_def subst_atm_mset_def by auto lemma mset_subst_cls_list_subst_cls_mset: "mset (Cs \cl \) = (mset Cs) \cm \" unfolding subst_cls_mset_def subst_cls_list_def by auto lemma sum_list_subst_cls_list_subst_cls[simp]: "sum_list (Cs \cl \) = sum_list Cs \ \" unfolding subst_cls_list_def by (induction Cs) auto lemma set_mset_subst_cls_mset_subst_clss: "set_mset (CC \cm \) = (set_mset CC) \cs \" by (simp add: subst_cls_mset_def subst_clss_def) lemma Neg_Melem_subst_atm_subst_cls[simp]: "Neg A \# C \ Neg (A \a \) \# C \ \ " by (metis Melem_subst_cls eql_neg_lit_eql_atm) lemma Pos_Melem_subst_atm_subst_cls[simp]: "Pos A \# C \ Pos (A \a \) \# C \ \ " by (metis Melem_subst_cls eql_pos_lit_eql_atm) lemma in_atms_of_subst[simp]: "B \ atms_of C \ B \a \ \ atms_of (C \ \)" by (metis atms_of_subst_atms image_iff subst_atms_def) subsubsection \Renamings\ lemma is_renaming_id_subst[simp]: "is_renaming id_subst" unfolding is_renaming_def by simp lemma is_renamingD: "is_renaming \ \ (\A1 A2. A1 \a \ = A2 \a \ \ A1 = A2)" by (metis is_renaming_def subst_atm_comp_subst subst_atm_id_subst) lemma inv_renaming_cancel_r[simp]: "is_renaming r \ r \ inv_renaming r = id_subst" unfolding inv_renaming_def is_renaming_def by (metis (mono_tags) someI_ex) lemma inv_renaming_cancel_r_list[simp]: "is_renaming_list rs \ rs \s map inv_renaming rs = replicate (length rs) id_subst" unfolding is_renaming_list_def by (induction rs) (auto simp add: comp_substs_def) lemma Nil_comp_substs[simp]: "[] \s s = []" unfolding comp_substs_def by auto lemma comp_substs_Nil[simp]: "s \s [] = []" unfolding comp_substs_def by auto lemma is_renaming_idempotent_id_subst: "is_renaming r \ r \ r = r \ r = id_subst" by (metis comp_subst_assoc comp_subst_id_subst inv_renaming_cancel_r) lemma is_renaming_left_id_subst_right_id_subst: "is_renaming r \ s \ r = id_subst \ r \ s = id_subst" by (metis comp_subst_assoc comp_subst_id_subst is_renaming_def) lemma is_renaming_closure: "is_renaming r1 \ is_renaming r2 \ is_renaming (r1 \ r2)" unfolding is_renaming_def by (metis comp_subst_assoc comp_subst_id_subst) lemma is_renaming_inv_renaming_cancel_atm[simp]: "is_renaming \ \ A \a \ \a inv_renaming \ = A" by (metis inv_renaming_cancel_r subst_atm_comp_subst subst_atm_id_subst) lemma is_renaming_inv_renaming_cancel_atms[simp]: "is_renaming \ \ AA \as \ \as inv_renaming \ = AA" by (metis inv_renaming_cancel_r subst_atms_comp_subst subst_atms_id_subst) lemma is_renaming_inv_renaming_cancel_atmss[simp]: "is_renaming \ \ AAA \ass \ \ass inv_renaming \ = AAA" by (metis inv_renaming_cancel_r subst_atmss_comp_subst subst_atmss_id_subst) lemma is_renaming_inv_renaming_cancel_atm_list[simp]: "is_renaming \ \ As \al \ \al inv_renaming \ = As" by (metis inv_renaming_cancel_r subst_atm_list_comp_subst subst_atm_list_id_subst) lemma is_renaming_inv_renaming_cancel_atm_mset[simp]: "is_renaming \ \ AA \am \ \am inv_renaming \ = AA" by (metis inv_renaming_cancel_r subst_atm_mset_comp_subst subst_atm_mset_id_subst) lemma is_renaming_inv_renaming_cancel_atm_mset_list[simp]: "is_renaming \ \ (AAs \aml \) \aml inv_renaming \ = AAs" by (metis inv_renaming_cancel_r subst_atm_mset_list_comp_subst subst_atm_mset_list_id_subst) lemma is_renaming_list_inv_renaming_cancel_atm_mset_lists[simp]: "length AAs = length \s \ is_renaming_list \s \ AAs \\aml \s \\aml map inv_renaming \s = AAs" by (metis inv_renaming_cancel_r_list subst_atm_mset_lists_comp_substs subst_atm_mset_lists_id_subst) lemma is_renaming_inv_renaming_cancel_lit[simp]: "is_renaming \ \ (L \l \) \l inv_renaming \ = L" by (metis inv_renaming_cancel_r subst_lit_comp_subst subst_lit_id_subst) lemma is_renaming_inv_renaming_cancel_cls[simp]: "is_renaming \ \ C \ \ \ inv_renaming \ = C" by (metis inv_renaming_cancel_r subst_cls_comp_subst subst_cls_id_subst) lemma is_renaming_inv_renaming_cancel_clss[simp]: "is_renaming \ \ CC \cs \ \cs inv_renaming \ = CC" by (metis inv_renaming_cancel_r subst_clss_id_subst subst_clsscomp_subst) lemma is_renaming_inv_renaming_cancel_cls_list[simp]: "is_renaming \ \ Cs \cl \ \cl inv_renaming \ = Cs" by (metis inv_renaming_cancel_r subst_cls_list_comp_subst subst_cls_list_id_subst) lemma is_renaming_list_inv_renaming_cancel_cls_list[simp]: "length Cs = length \s \ is_renaming_list \s \ Cs \\cl \s \\cl map inv_renaming \s = Cs" by (metis inv_renaming_cancel_r_list subst_cls_lists_comp_substs subst_cls_lists_id_subst) lemma is_renaming_inv_renaming_cancel_cls_mset[simp]: "is_renaming \ \ CC \cm \ \cm inv_renaming \ = CC" by (metis inv_renaming_cancel_r subst_cls_mset_comp_subst subst_cls_mset_id_subst) subsubsection \Monotonicity\ lemma subst_cls_mono: "set_mset C \ set_mset D \ set_mset (C \ \) \ set_mset (D \ \)" by force lemma subst_cls_mono_mset: "C \# D \ C \ \ \# D \ \" unfolding subst_clss_def by (metis mset_subset_eq_exists_conv subst_cls_union) lemma subst_subset_mono: "D \# C \ D \ \ \# C \ \" unfolding subst_cls_def by (simp add: image_mset_subset_mono) subsubsection \Size after Substitution\ lemma size_subst[simp]: "size (D \ \) = size D" unfolding subst_cls_def by auto lemma subst_atm_list_length[simp]: "length (As \al \) = length As" unfolding subst_atm_list_def by auto lemma length_subst_atm_mset_list[simp]: "length (AAs \aml \) = length AAs" unfolding subst_atm_mset_list_def by auto lemma subst_atm_mset_lists_length[simp]: "length (AAs \\aml \s) = min (length AAs) (length \s)" unfolding subst_atm_mset_lists_def by auto lemma subst_cls_list_length[simp]: "length (Cs \cl \) = length Cs" unfolding subst_cls_list_def by auto lemma comp_substs_length[simp]: "length (\s \s \s) = min (length \s) (length \s)" unfolding comp_substs_def by auto lemma subst_cls_lists_length[simp]: "length (Cs \\cl \s) = min (length Cs) (length \s)" unfolding subst_cls_lists_def by auto subsubsection \Variable Disjointness\ lemma var_disjoint_clauses: assumes "var_disjoint Cs" shows "\\s. length \s = length Cs \ (\\. Cs \\cl \s = Cs \cl \)" proof clarify fix \s :: "'s list" assume a: "length \s = length Cs" then obtain \ where "\i < length Cs. \S. S \# Cs ! i \ S \ \s ! i = S \ \" using assms unfolding var_disjoint_def by blast then have "\i < length Cs. (Cs ! i) \ \s ! i = (Cs ! i) \ \" by auto then have "Cs \\cl \s = Cs \cl \" using a by (auto intro: nth_equalityI) then show "\\. Cs \\cl \s = Cs \cl \" by auto qed subsubsection \Ground Expressions and Substitutions\ lemma ex_ground_subst: "\\. is_ground_subst \" using make_ground_subst[of "{#}"] by (simp add: is_ground_cls_def) lemma is_ground_cls_list_Cons[simp]: "is_ground_cls_list (C # Cs) = (is_ground_cls C \ is_ground_cls_list Cs)" unfolding is_ground_cls_list_def by auto paragraph \Ground union\ lemma is_ground_atms_union[simp]: "is_ground_atms (AA \ BB) \ is_ground_atms AA \ is_ground_atms BB" unfolding is_ground_atms_def by auto lemma is_ground_atm_mset_union[simp]: "is_ground_atm_mset (AA + BB) \ is_ground_atm_mset AA \ is_ground_atm_mset BB" unfolding is_ground_atm_mset_def by auto lemma is_ground_cls_union[simp]: "is_ground_cls (C + D) \ is_ground_cls C \ is_ground_cls D" unfolding is_ground_cls_def by auto lemma is_ground_clss_union[simp]: "is_ground_clss (CC \ DD) \ is_ground_clss CC \ is_ground_clss DD" unfolding is_ground_clss_def by auto lemma is_ground_cls_list_is_ground_cls_sum_list[simp]: "is_ground_cls_list Cs \ is_ground_cls (sum_list Cs)" by (meson in_mset_sum_list2 is_ground_cls_def is_ground_cls_list_def) paragraph \Grounding monotonicity\ lemma is_ground_cls_mono: "C \# D \ is_ground_cls D \ is_ground_cls C" unfolding is_ground_cls_def by (metis set_mset_mono subsetD) lemma is_ground_clss_mono: "CC \ DD \ is_ground_clss DD \ is_ground_clss CC" unfolding is_ground_clss_def by blast lemma grounding_of_clss_mono: "CC \ DD \ grounding_of_clss CC \ grounding_of_clss DD" using grounding_of_clss_def by auto lemma sum_list_subseteq_mset_is_ground_cls_list[simp]: "sum_list Cs \# sum_list Ds \ is_ground_cls_list Ds \ is_ground_cls_list Cs" by (meson in_mset_sum_list is_ground_cls_def is_ground_cls_list_is_ground_cls_sum_list is_ground_cls_mono is_ground_cls_list_def) paragraph \Substituting on ground expression preserves ground\ lemma is_ground_comp_subst[simp]: "is_ground_subst \ \ is_ground_subst (\ \ \)" unfolding is_ground_subst_def is_ground_atm_def by auto lemma ground_subst_ground_atm[simp]: "is_ground_subst \ \ is_ground_atm (A \a \)" by (simp add: is_ground_subst_def) lemma ground_subst_ground_lit[simp]: "is_ground_subst \ \ is_ground_lit (L \l \)" unfolding is_ground_lit_def subst_lit_def by (cases L) auto lemma ground_subst_ground_cls[simp]: "is_ground_subst \ \ is_ground_cls (C \ \)" unfolding is_ground_cls_def by auto lemma ground_subst_ground_clss[simp]: "is_ground_subst \ \ is_ground_clss (CC \cs \)" unfolding is_ground_clss_def subst_clss_def by auto lemma ground_subst_ground_cls_list[simp]: "is_ground_subst \ \ is_ground_cls_list (Cs \cl \)" unfolding is_ground_cls_list_def subst_cls_list_def by auto lemma ground_subst_ground_cls_lists[simp]: "\\ \ set \s. is_ground_subst \ \ is_ground_cls_list (Cs \\cl \s)" unfolding is_ground_cls_list_def subst_cls_lists_def by (auto simp: set_zip) lemma subst_cls_eq_grounding_of_cls_subset_eq: assumes "D \ \ = C" shows "grounding_of_cls C \ grounding_of_cls D" proof fix C\' assume "C\' \ grounding_of_cls C" then obtain \' where C\': "C \ \' = C\'" "is_ground_subst \'" unfolding grounding_of_cls_def by auto then have "C \ \' = D \ \ \ \' \ is_ground_subst (\ \ \')" using assms by auto then show "C\' \ grounding_of_cls D" unfolding grounding_of_cls_def using C\'(1) by force qed paragraph \Substituting on ground expression has no effect\ lemma is_ground_subst_atm[simp]: "is_ground_atm A \ A \a \ = A" unfolding is_ground_atm_def by simp lemma is_ground_subst_atms[simp]: "is_ground_atms AA \ AA \as \ = AA" unfolding is_ground_atms_def subst_atms_def image_def by auto lemma is_ground_subst_atm_mset[simp]: "is_ground_atm_mset AA \ AA \am \ = AA" unfolding is_ground_atm_mset_def subst_atm_mset_def by auto lemma is_ground_subst_atm_list[simp]: "is_ground_atm_list As \ As \al \ = As" unfolding is_ground_atm_list_def subst_atm_list_def by (auto intro: nth_equalityI) lemma is_ground_subst_atm_list_member[simp]: "is_ground_atm_list As \ i < length As \ As ! i \a \ = As ! i" unfolding is_ground_atm_list_def by auto lemma is_ground_subst_lit[simp]: "is_ground_lit L \ L \l \ = L" unfolding is_ground_lit_def subst_lit_def by (cases L) simp_all lemma is_ground_subst_cls[simp]: "is_ground_cls C \ C \ \ = C" unfolding is_ground_cls_def subst_cls_def by simp lemma is_ground_subst_clss[simp]: "is_ground_clss CC \ CC \cs \ = CC" unfolding is_ground_clss_def subst_clss_def image_def by auto lemma is_ground_subst_cls_lists[simp]: assumes "length P = length Cs" and "is_ground_cls_list Cs" shows "Cs \\cl P = Cs" using assms by (metis is_ground_cls_list_def is_ground_subst_cls min.idem nth_equalityI nth_mem subst_cls_lists_nth subst_cls_lists_length) lemma is_ground_subst_lit_iff: "is_ground_lit L \ (\\. L = L \l \)" using is_ground_atm_def is_ground_lit_def subst_lit_def by (cases L) auto lemma is_ground_subst_cls_iff: "is_ground_cls C \ (\\. C = C \ \)" by (metis ex_ground_subst ground_subst_ground_cls is_ground_subst_cls) paragraph \Members of ground expressions are ground\ lemma is_ground_cls_as_atms: "is_ground_cls C \ (\A \ atms_of C. is_ground_atm A)" by (auto simp: atms_of_def is_ground_cls_def is_ground_lit_def) lemma is_ground_cls_imp_is_ground_lit: "L \# C \ is_ground_cls C \ is_ground_lit L" by (simp add: is_ground_cls_def) lemma is_ground_cls_imp_is_ground_atm: "A \ atms_of C \ is_ground_cls C \ is_ground_atm A" by (simp add: is_ground_cls_as_atms) lemma is_ground_cls_is_ground_atms_atms_of[simp]: "is_ground_cls C \ is_ground_atms (atms_of C)" by (simp add: is_ground_cls_imp_is_ground_atm is_ground_atms_def) lemma grounding_ground: "C \ grounding_of_clss M \ is_ground_cls C" unfolding grounding_of_clss_def grounding_of_cls_def by auto lemma in_subset_eq_grounding_of_clss_is_ground_cls[simp]: "C \ CC \ CC \ grounding_of_clss DD \ is_ground_cls C" unfolding grounding_of_clss_def grounding_of_cls_def by auto lemma is_ground_cls_empty[simp]: "is_ground_cls {#}" unfolding is_ground_cls_def by simp lemma grounding_of_cls_ground: "is_ground_cls C \ grounding_of_cls C = {C}" unfolding grounding_of_cls_def by (simp add: ex_ground_subst) lemma grounding_of_cls_empty[simp]: "grounding_of_cls {#} = {{#}}" by (simp add: grounding_of_cls_ground) +lemma union_grounding_of_cls_ground: "is_ground_clss (\ (grounding_of_cls ` N))" + by (simp add: grounding_ground grounding_of_clss_def is_ground_clss_def) + paragraph \Grounding idempotence\ lemma grounding_of_grounding_of_cls: "E \ grounding_of_cls D \ D \ grounding_of_cls C \ E = D" using grounding_of_cls_def by auto subsubsection \Subsumption\ lemma subsumes_empty_left[simp]: "subsumes {#} C" unfolding subsumes_def subst_cls_def by simp lemma strictly_subsumes_empty_left[simp]: "strictly_subsumes {#} C \ C \ {#}" unfolding strictly_subsumes_def subsumes_def subst_cls_def by simp subsubsection \Unifiers\ lemma card_le_one_alt: "finite X \ card X \ 1 \ X = {} \ (\x. X = {x})" by (induct rule: finite_induct) auto lemma is_unifier_subst_atm_eqI: assumes "finite AA" shows "is_unifier \ AA \ A \ AA \ B \ AA \ A \a \ = B \a \" unfolding is_unifier_def subst_atms_def card_le_one_alt[OF finite_imageI[OF assms]] by (metis equals0D imageI insert_iff) lemma is_unifier_alt: assumes "finite AA" shows "is_unifier \ AA \ (\A \ AA. \B \ AA. A \a \ = B \a \)" unfolding is_unifier_def subst_atms_def card_le_one_alt[OF finite_imageI[OF assms(1)]] by (rule iffI, metis empty_iff insert_iff insert_image, blast) lemma is_unifiers_subst_atm_eqI: assumes "finite AA" "is_unifiers \ AAA" "AA \ AAA" "A \ AA" "B \ AA" shows "A \a \ = B \a \" by (metis assms is_unifiers_def is_unifier_subst_atm_eqI) theorem is_unifiers_comp: "is_unifiers \ (set_mset ` set (map2 add_mset As Bs) \ass \) \ is_unifiers (\ \ \) (set_mset ` set (map2 add_mset As Bs))" unfolding is_unifiers_def is_unifier_def subst_atmss_def by auto subsubsection \Most General Unifier\ lemma is_mgu_is_unifiers: "is_mgu \ AAA \ is_unifiers \ AAA" using is_mgu_def by blast lemma is_mgu_is_most_general: "is_mgu \ AAA \ is_unifiers \ AAA \ \\. \ = \ \ \" using is_mgu_def by blast lemma is_unifiers_is_unifier: "is_unifiers \ AAA \ AA \ AAA \ is_unifier \ AA" using is_unifiers_def by simp subsubsection \Generalization and Subsumption\ lemma variants_sym: "variants D D' \ variants D' D" unfolding variants_def by auto lemma variants_iff_subsumes: "variants C D \ subsumes C D \ subsumes D C" proof assume "variants C D" then show "subsumes C D \ subsumes D C" unfolding variants_def generalizes_def subsumes_def by (metis subset_mset.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/Saturation_Framework/Labeled_Lifting_to_Non_Ground_Calculi.thy b/thys/Saturation_Framework/Labeled_Lifting_to_Non_Ground_Calculi.thy --- a/thys/Saturation_Framework/Labeled_Lifting_to_Non_Ground_Calculi.thy +++ b/thys/Saturation_Framework/Labeled_Lifting_to_Non_Ground_Calculi.thy @@ -1,361 +1,356 @@ (* Title: Labeled Lifting to Non-Ground Calculi of the Saturation Framework * Author: Sophie Tourret , 2019-2020 *) section \Labeled Liftings\ text \This section formalizes the extension of the lifting results to labeled calculi. This corresponds to section 3.4 of the report.\ theory Labeled_Lifting_to_Non_Ground_Calculi imports Lifting_to_Non_Ground_Calculi begin subsection \Labeled Lifting with a Family of Well-founded Orderings\ locale labeled_lifting_w_wf_ord_family = no_labels: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F \_Inf Prec_F for Bot_F :: "'f set" and Inf_F :: "'f inference set" and Bot_G :: "'g set" and entails_G :: "'g set \ 'g set \ bool" (infix "\G" 50) and Inf_G :: "'g inference set" and Red_Inf_G :: "'g set \ 'g inference set" and Red_F_G :: "'g set \ 'g set" and \_F :: "'f \ 'g set" and \_Inf :: "'f inference \ 'g inference set option" and Prec_F :: "'g \ 'f \ 'f \ bool" (infix "\" 50) + fixes Inf_FL :: \('f \ 'l) inference set\ assumes Inf_F_to_Inf_FL: \\\<^sub>F \ Inf_F \ length (Ll :: 'l list) = length (prems_of \\<^sub>F) \ \L0. Infer (zip (prems_of \\<^sub>F) Ll) (concl_of \\<^sub>F, L0) \ Inf_FL\ and Inf_FL_to_Inf_F: \\\<^sub>F\<^sub>L \ Inf_FL \ Infer (map fst (prems_of \\<^sub>F\<^sub>L)) (fst (concl_of \\<^sub>F\<^sub>L)) \ Inf_F\ begin definition to_F :: \('f \ 'l) inference \ 'f inference\ where \to_F \\<^sub>F\<^sub>L = Infer (map fst (prems_of \\<^sub>F\<^sub>L)) (fst (concl_of \\<^sub>F\<^sub>L))\ abbreviation Bot_FL :: \('f \ 'l) set\ where \Bot_FL \ Bot_F \ UNIV\ abbreviation \_F_L :: \('f \ 'l) \ 'g set\ where \\_F_L CL \ \_F (fst CL)\ abbreviation \_Inf_L :: \('f \ 'l) inference \ 'g inference set option\ where \\_Inf_L \\<^sub>F\<^sub>L \ \_Inf (to_F \\<^sub>F\<^sub>L)\ (* lem:labeled-grounding-function *) sublocale standard_lifting Bot_FL Inf_FL Bot_G Inf_G "(\G)" Red_Inf_G Red_F_G \_F_L \_Inf_L proof show "Bot_FL \ {}" using no_labels.Bot_F_not_empty by simp next show "B \ Bot_FL \ \_F_L B \ {}" for B using no_labels.Bot_map_not_empty by auto next show "B \ Bot_FL \ \_F_L B \ Bot_G" for B using no_labels.Bot_map by force next fix CL show "\_F_L CL \ Bot_G \ {} \ CL \ Bot_FL" using no_labels.Bot_cond by (metis SigmaE UNIV_I UNIV_Times_UNIV mem_Sigma_iff prod.sel(1)) next fix \ assume i_in: \\ \ Inf_FL\ and ground_not_none: \\_Inf_L \ \ None\ then show "the (\_Inf_L \) \ Red_Inf_G (\_F_L (concl_of \))" unfolding to_F_def using no_labels.inf_map Inf_FL_to_Inf_F by fastforce qed sublocale lifting_with_wf_ordering_family Bot_FL Inf_FL Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F_L \_Inf_L "\g Cl Cl'. False" -proof - show "po_on (\Cl Cl'. False) UNIV" - unfolding po_on_def by (simp add: transp_onI wfp_on_imp_irreflp_on) - show "wfp_on (\Cl Cl'. False) UNIV" - unfolding wfp_on_def by simp -qed + by unfold_locales simp+ notation entails_\ (infix "\\L" 50) (* lem:labeled-consequence *) lemma labeled_entailment_lifting: "NL1 \\L NL2 \ fst ` NL1 \\ fst ` NL2" by simp lemma red_inf_impl: "\ \ Red_Inf_\ NL \ to_F \ \ no_labels.Red_Inf_\ (fst ` NL)" unfolding Red_Inf_\_def no_labels.Red_Inf_\_def using Inf_FL_to_Inf_F by (auto simp: to_F_def) (* lem:labeled-saturation *) lemma labeled_saturation_lifting: "saturated NL \ no_labels.saturated (fst ` NL)" unfolding saturated_def no_labels.saturated_def Inf_from_def no_labels.Inf_from_def proof clarify fix \ assume subs_Red_Inf: "{\ \ Inf_FL. set (prems_of \) \ NL} \ Red_Inf_\ NL" and i_in: "\ \ Inf_F" and i_prems: "set (prems_of \) \ fst ` NL" define Lli where "Lli i = (SOME x. ((prems_of \)!i,x) \ NL)" for i have [simp]:"((prems_of \)!i,Lli i) \ NL" if "i < length (prems_of \)" for i using that i_prems unfolding Lli_def by (metis nth_mem someI_ex DomainE Domain_fst subset_eq) define Ll where "Ll = map Lli [0..)]" have Ll_length: "length Ll = length (prems_of \)" unfolding Ll_def by auto have subs_NL: "set (zip (prems_of \) Ll) \ NL" unfolding Ll_def by (auto simp:in_set_zip) obtain L0 where L0: "Infer (zip (prems_of \) Ll) (concl_of \, L0) \ Inf_FL" using Inf_F_to_Inf_FL[OF i_in Ll_length] .. define \_FL where "\_FL = Infer (zip (prems_of \) Ll) (concl_of \, L0)" then have "set (prems_of \_FL) \ NL" using subs_NL by simp then have "\_FL \ {\ \ Inf_FL. set (prems_of \) \ NL}" unfolding \_FL_def using L0 by blast then have "\_FL \ Red_Inf_\ NL" using subs_Red_Inf by fast moreover have "\ = to_F \_FL" unfolding to_F_def \_FL_def using Ll_length by (cases \) auto ultimately show "\ \ no_labels.Red_Inf_\ (fst ` NL)" by (auto intro: red_inf_impl) qed (* lem:labeled-static-ref-compl *) lemma stat_ref_comp_to_labeled_sta_ref_comp: assumes static: "static_refutational_complete_calculus Bot_F Inf_F (\\) no_labels.Red_Inf_\ no_labels.Red_F_\" shows "static_refutational_complete_calculus Bot_FL Inf_FL (\\L) Red_Inf_\ Red_F_\" proof fix Bl :: \'f \ 'l\ and Nl :: \('f \ 'l) set\ assume Bl_in: \Bl \ Bot_FL\ and Nl_sat: \saturated Nl\ and Nl_entails_Bl: \Nl \\L {Bl}\ define B where "B = fst Bl" have B_in: "B \ Bot_F" using Bl_in B_def SigmaE by force define N where "N = fst ` Nl" have N_sat: "no_labels.saturated N" using N_def Nl_sat labeled_saturation_lifting by blast have N_entails_B: "N \\ {B}" using Nl_entails_Bl unfolding labeled_entailment_lifting N_def B_def by force have "\B' \ Bot_F. B' \ N" using B_in N_sat N_entails_B using static[unfolded static_refutational_complete_calculus_def static_refutational_complete_calculus_axioms_def] by blast then obtain B' where in_Bot: "B' \ Bot_F" and in_N: "B' \ N" by force then have "B' \ fst ` Bot_FL" by fastforce obtain Bl' where in_Nl: "Bl' \ Nl" and fst_Bl': "fst Bl' = B'" using in_N unfolding N_def by blast have "Bl' \ Bot_FL" using fst_Bl' in_Bot vimage_fst by fastforce then show \\Bl'\Bot_FL. Bl' \ Nl\ using in_Nl by blast qed end subsection \Labeled Lifting with a Family of Redundancy Criteria\ locale labeled_lifting_with_red_crit_family = no_labels: standard_lifting_with_red_crit_family Inf_F Bot_G Q Inf_G_q entails_q Red_Inf_q Red_F_q Bot_F \_F_q \_Inf_q "\g Cl Cl'. False" for Bot_F :: "'f set" and Inf_F :: "'f inference set" and Bot_G :: "'g set" and Q :: "'q set" and entails_q :: "'q \ 'g set \ 'g set \ bool" and Inf_G_q :: "'q \ 'g inference set" and Red_Inf_q :: "'q \ 'g set \ 'g inference set" and Red_F_q :: "'q \ 'g set \ 'g set" and \_F_q :: "'q \ 'f \ 'g set" and \_Inf_q :: "'q \ 'f inference \ 'g inference set option" + fixes Inf_FL :: \('f \ 'l) inference set\ assumes Inf_F_to_Inf_FL: \\\<^sub>F \ Inf_F \ length (Ll :: 'l list) = length (prems_of \\<^sub>F) \ \L0. Infer (zip (prems_of \\<^sub>F) Ll) (concl_of \\<^sub>F, L0) \ Inf_FL\ and Inf_FL_to_Inf_F: \\\<^sub>F\<^sub>L \ Inf_FL \ Infer (map fst (prems_of \\<^sub>F\<^sub>L)) (fst (concl_of \\<^sub>F\<^sub>L)) \ Inf_F\ begin definition to_F :: \('f \ 'l) inference \ 'f inference\ where \to_F \\<^sub>F\<^sub>L = Infer (map fst (prems_of \\<^sub>F\<^sub>L)) (fst (concl_of \\<^sub>F\<^sub>L))\ abbreviation Bot_FL :: \('f \ 'l) set\ where \Bot_FL \ Bot_F \ UNIV\ abbreviation \_F_L_q :: \'q \ ('f \ 'l) \ 'g set\ where \\_F_L_q q CL \ \_F_q q (fst CL)\ abbreviation \_Inf_L_q :: \'q \ ('f \ 'l) inference \ 'g inference set option\ where \\_Inf_L_q q \\<^sub>F\<^sub>L \ \_Inf_q q (to_F \\<^sub>F\<^sub>L)\ abbreviation \_set_L_q :: "'q \ ('f \ 'l) set \ 'g set" where "\_set_L_q q N \ \ (\_F_L_q q ` N)" definition Red_Inf_\_L_q :: "'q \ ('f \ 'l) set \ ('f \ 'l) inference set" where "Red_Inf_\_L_q q N = {\ \ Inf_FL. (\_Inf_L_q q \ \ None \ the (\_Inf_L_q q \) \ Red_Inf_q q (\_set_L_q q N)) \ (\_Inf_L_q q \ = None \ \_F_L_q q (concl_of \) \ \_set_L_q q N \ Red_F_q q (\_set_L_q q N))}" abbreviation Red_Inf_\_L_Q :: "('f \ 'l) set \ ('f \ 'l) inference set" where "Red_Inf_\_L_Q N \ (\q \ Q. Red_Inf_\_L_q q N)" abbreviation entails_\_L_q :: "'q \ ('f \ 'l) set \ ('f \ 'l) set \ bool" where "entails_\_L_q q N1 N2 \ entails_q q (\_set_L_q q N1) (\_set_L_q q N2)" lemma lifting_q: assumes "q \ Q" shows "labeled_lifting_w_wf_ord_family Bot_F Inf_F Bot_G (entails_q q) (Inf_G_q q) (Red_Inf_q q) (Red_F_q q) (\_F_q q) (\_Inf_q q) (\g Cl Cl'. False) Inf_FL" using assms no_labels.standard_lifting_family Inf_F_to_Inf_FL Inf_FL_to_Inf_F by (simp add: labeled_lifting_w_wf_ord_family_axioms_def labeled_lifting_w_wf_ord_family_def) lemma lifted_q: assumes q_in: "q \ Q" shows "standard_lifting Bot_FL Inf_FL Bot_G (Inf_G_q q) (entails_q q) (Red_Inf_q q) (Red_F_q q) (\_F_L_q q) (\_Inf_L_q q)" proof - interpret q_lifting: labeled_lifting_w_wf_ord_family Bot_F Inf_F Bot_G "entails_q q" "Inf_G_q q" "Red_Inf_q q" "Red_F_q q" "\_F_q q" "\_Inf_q q" "\g Cl Cl'. False" Inf_FL using lifting_q[OF q_in] . have "\_Inf_L_q q = q_lifting.\_Inf_L" unfolding to_F_def q_lifting.to_F_def by simp then show ?thesis using q_lifting.standard_lifting_axioms by simp qed lemma ord_fam_lifted_q: assumes q_in: "q \ Q" shows "lifting_with_wf_ordering_family Bot_FL Inf_FL Bot_G (entails_q q) (Inf_G_q q) (Red_Inf_q q) (Red_F_q q) (\_F_L_q q) (\_Inf_L_q q) (\g Cl Cl'. False)" proof - interpret standard_q_lifting: standard_lifting Bot_FL Inf_FL Bot_G "Inf_G_q q" "entails_q q" "Red_Inf_q q" "Red_F_q q" "\_F_L_q q" "\_Inf_L_q q" using lifted_q[OF q_in] . have "minimal_element (\Cl Cl'. False) UNIV" by (simp add: minimal_element.intro po_on_def transp_onI wfp_on_imp_irreflp_on) then show ?thesis using standard_q_lifting.standard_lifting_axioms by (simp add: lifting_with_wf_ordering_family_axioms_def lifting_with_wf_ordering_family_def) qed definition Red_F_\_empty_L_q :: "'q \ ('f \ 'l) set \ ('f \ 'l) set" where "Red_F_\_empty_L_q q N = {C. \D \ \_F_L_q q C. D \ Red_F_q q (\_set_L_q q N) \ (\E \ N. False \ D \ \_F_L_q q E)}" abbreviation Red_F_\_empty_L :: "('f \ 'l) set \ ('f \ 'l) set" where "Red_F_\_empty_L N \ (\q \ Q. Red_F_\_empty_L_q q N)" lemma all_lifted_red_crit: assumes q_in: "q \ Q" shows "calculus_with_red_crit Bot_FL Inf_FL (entails_\_L_q q) (Red_Inf_\_L_q q) (Red_F_\_empty_L_q q)" proof - interpret ord_q_lifting: lifting_with_wf_ordering_family Bot_FL Inf_FL Bot_G "entails_q q" "Inf_G_q q" "Red_Inf_q q" "Red_F_q q" "\_F_L_q q" "\_Inf_L_q q" "\g Cl Cl'. False" using ord_fam_lifted_q[OF q_in] . have "Red_Inf_\_L_q q = ord_q_lifting.Red_Inf_\" unfolding Red_Inf_\_L_q_def ord_q_lifting.Red_Inf_\_def by simp moreover have "Red_F_\_empty_L_q q = ord_q_lifting.Red_F_\" unfolding Red_F_\_empty_L_q_def ord_q_lifting.Red_F_\_def by simp ultimately show ?thesis using ord_q_lifting.calculus_with_red_crit_axioms by argo qed lemma all_lifted_cons_rel: assumes q_in: "q \ Q" shows "consequence_relation Bot_FL (entails_\_L_q q)" using all_lifted_red_crit calculus_with_red_crit_def q_in by blast sublocale consequence_relation_family Bot_FL Q entails_\_L_q using all_lifted_cons_rel by (simp add: consequence_relation_family.intro no_labels.Q_nonempty) sublocale calculus_with_red_crit_family Bot_FL Inf_FL Q entails_\_L_q Red_Inf_\_L_q Red_F_\_empty_L_q using calculus_with_red_crit_family.intro[OF consequence_relation_family_axioms] by (simp add: all_lifted_red_crit calculus_with_red_crit_family_axioms_def no_labels.Q_nonempty) notation no_labels.entails_\_Q (infix "\\\" 50) abbreviation entails_\_L_Q :: "('f \ 'l) set \ ('f \ 'l) set \ bool" (infix "\\\L" 50) where "(\\\L) \ entails_Q" lemmas entails_\_L_Q_def = entails_Q_def (* lem:labeled-consequence-intersection *) lemma labeled_entailment_lifting: "NL1 \\\L NL2 \ fst ` NL1 \\\ fst ` NL2" unfolding no_labels.entails_\_Q_def entails_\_L_Q_def by force lemma red_inf_impl: "\ \ Red_Inf_Q NL \ to_F \ \ no_labels.Red_Inf_\_Q (fst ` NL)" unfolding no_labels.Red_Inf_\_Q_def Red_Inf_Q_def proof clarify fix X Xa q assume q_in: "q \ Q" and i_in_inter: "\ \ (\q \ Q. Red_Inf_\_L_q q NL)" have i_in_q: "\ \ Red_Inf_\_L_q q NL" using q_in i_in_inter image_eqI by blast then have i_in: "\ \ Inf_FL" unfolding Red_Inf_\_L_q_def by blast have to_F_in: "to_F \ \ Inf_F" unfolding to_F_def using Inf_FL_to_Inf_F[OF i_in] . have rephrase1: "(\CL\NL. \_F_q q (fst CL)) = (\ (\_F_q q ` fst ` NL))" by blast have rephrase2: "fst (concl_of \) = concl_of (to_F \)" unfolding concl_of_def to_F_def by simp have subs_red: "(\_Inf_L_q q \ \ None \ the (\_Inf_L_q q \) \ Red_Inf_q q (\_set_L_q q NL)) \ (\_Inf_L_q q \ = None \ \_F_L_q q (concl_of \) \ \_set_L_q q NL \ Red_F_q q (\_set_L_q q NL))" using i_in_q unfolding Red_Inf_\_L_q_def by blast then have to_F_subs_red: "(\_Inf_q q (to_F \) \ None \ the (\_Inf_q q (to_F \)) \ Red_Inf_q q (no_labels.\_set_q q (fst ` NL))) \ (\_Inf_q q (to_F \) = None \ \_F_q q (concl_of (to_F \)) \ no_labels.\_set_q q (fst ` NL) \ Red_F_q q (no_labels.\_set_q q (fst ` NL)))" using rephrase1 rephrase2 by metis then show "to_F \ \ no_labels.Red_Inf_\_q q (fst ` NL)" using to_F_in unfolding no_labels.Red_Inf_\_q_def by simp qed (* lem:labeled-saturation-intersection *) lemma labeled_family_saturation_lifting: "saturated NL \ no_labels.saturated (fst ` NL)" unfolding saturated_def no_labels.saturated_def Inf_from_def no_labels.Inf_from_def proof clarify fix \F assume labeled_sat: "{\ \ Inf_FL. set (prems_of \) \ NL} \ Red_Inf_Q NL" and iF_in: "\F \ Inf_F" and iF_prems: "set (prems_of \F) \ fst ` NL" define Lli where "Lli i = (SOME x. ((prems_of \F)!i,x) \ NL)" for i have [simp]:"((prems_of \F)!i,Lli i) \ NL" if "i < length (prems_of \F)" for i using that iF_prems nth_mem someI_ex unfolding Lli_def by (metis DomainE Domain_fst subset_eq) define Ll where "Ll = map Lli [0..F)]" have Ll_length: "length Ll = length (prems_of \F)" unfolding Ll_def by auto have subs_NL: "set (zip (prems_of \F) Ll) \ NL" unfolding Ll_def by (auto simp:in_set_zip) obtain L0 where L0: "Infer (zip (prems_of \F) Ll) (concl_of \F, L0) \ Inf_FL" using Inf_F_to_Inf_FL[OF iF_in Ll_length] .. define \FL where "\FL = Infer (zip (prems_of \F) Ll) (concl_of \F, L0)" then have "set (prems_of \FL) \ NL" using subs_NL by simp then have "\FL \ {\ \ Inf_FL. set (prems_of \) \ NL}" unfolding \FL_def using L0 by blast then have "\FL \ Red_Inf_Q NL" using labeled_sat by fast moreover have "\F = to_F \FL" unfolding to_F_def \FL_def using Ll_length by (cases \F) auto ultimately show "\F \ no_labels.Red_Inf_\_Q (fst ` NL)" by (auto intro: red_inf_impl) qed (* thm:labeled-static-ref-compl-intersection *) theorem labeled_static_ref: assumes calc: "static_refutational_complete_calculus Bot_F Inf_F (\\\) no_labels.Red_Inf_\_Q no_labels.Red_F_\_empty" shows "static_refutational_complete_calculus Bot_FL Inf_FL (\\\L) Red_Inf_Q Red_F_Q" proof fix Bl :: \'f \ 'l\ and Nl :: \('f \ 'l) set\ assume Bl_in: \Bl \ Bot_FL\ and Nl_sat: \saturated Nl\ and Nl_entails_Bl: \Nl \\\L {Bl}\ define B where "B = fst Bl" have B_in: "B \ Bot_F" using Bl_in B_def SigmaE by force define N where "N = fst ` Nl" have N_sat: "no_labels.saturated N" using N_def Nl_sat labeled_family_saturation_lifting by blast have N_entails_B: "N \\\ {B}" using Nl_entails_Bl unfolding labeled_entailment_lifting N_def B_def by force have "\B' \ Bot_F. B' \ N" using B_in N_sat N_entails_B calc[unfolded static_refutational_complete_calculus_def static_refutational_complete_calculus_axioms_def] by blast then obtain B' where in_Bot: "B' \ Bot_F" and in_N: "B' \ N" by force then have "B' \ fst ` Bot_FL" by fastforce obtain Bl' where in_Nl: "Bl' \ Nl" and fst_Bl': "fst Bl' = B'" using in_N unfolding N_def by blast have "Bl' \ Bot_FL" using fst_Bl' in_Bot vimage_fst by fastforce then show \\Bl'\Bot_FL. Bl' \ Nl\ using in_Nl by blast qed end end diff --git a/thys/Saturation_Framework/Lifting_to_Non_Ground_Calculi.thy b/thys/Saturation_Framework/Lifting_to_Non_Ground_Calculi.thy --- a/thys/Saturation_Framework/Lifting_to_Non_Ground_Calculi.thy +++ b/thys/Saturation_Framework/Lifting_to_Non_Ground_Calculi.thy @@ -1,754 +1,752 @@ (* Title: Lifting to Non-Ground Calculi of the Saturation Framework * Author: Sophie Tourret , 2018-2020 *) section \Lifting to Non-ground Calculi\ text \The section 3.1 to 3.3 of the report are covered by the current section. Various forms of lifting are proven correct. These allow to obtain the dynamic refutational completeness of a non-ground calculus from the static refutational completeness of its ground counterpart.\ theory Lifting_to_Non_Ground_Calculi imports Calculi Well_Quasi_Orders.Minimal_Elements begin subsection \Standard Lifting\ locale standard_lifting = inference_system Inf_F + ground: calculus_with_red_crit Bot_G Inf_G entails_G Red_Inf_G Red_F_G for Bot_F :: \'f set\ and Inf_F :: \'f inference set\ and Bot_G :: \'g set\ and Inf_G :: \'g inference set\ and entails_G :: \'g set \ 'g set \ bool\ (infix "\G" 50) and Red_Inf_G :: \'g set \ 'g inference set\ and Red_F_G :: \'g set \ 'g set\ + fixes \_F :: \'f \ 'g set\ and \_Inf :: \'f inference \ 'g inference set option\ assumes Bot_F_not_empty: "Bot_F \ {}" and Bot_map_not_empty: \B \ Bot_F \ \_F B \ {}\ and Bot_map: \B \ Bot_F \ \_F B \ Bot_G\ and Bot_cond: \\_F C \ Bot_G \ {} \ C \ Bot_F\ and inf_map: \\ \ Inf_F \ \_Inf \ \ None \ the (\_Inf \) \ Red_Inf_G (\_F (concl_of \))\ begin abbreviation \_set :: \'f set \ 'g set\ where \\_set N \ \ (\_F ` N)\ lemma \_subset: \N1 \ N2 \ \_set N1 \ \_set N2\ by auto abbreviation entails_\ :: \'f set \ 'f set \ bool\ (infix "\\" 50) where \N1 \\ N2 \ \_set N1 \G \_set N2\ lemma subs_Bot_G_entails: assumes not_empty: \sB \ {}\ and in_bot: \sB \ Bot_G\ shows \sB \G N\ proof - have \\B. B \ sB\ using not_empty by auto then obtain B where B_in: \B \ sB\ by auto then have r_trans: \{B} \G N\ using ground.bot_entails_all in_bot by auto have l_trans: \sB \G {B}\ using B_in ground.subset_entailed by auto then show ?thesis using r_trans ground.entails_trans[of sB "{B}"] by auto qed (* lem:derived-consequence-relation *) sublocale consequence_relation Bot_F entails_\ proof show "Bot_F \ {}" using Bot_F_not_empty . next show \B\Bot_F \ {B} \\ N\ for B N proof - assume \B \ Bot_F\ then show \{B} \\ N\ using Bot_map ground.bot_entails_all[of _ "\_set N"] subs_Bot_G_entails Bot_map_not_empty by auto qed next fix N1 N2 :: \'f set\ assume \N2 \ N1\ then show \N1 \\ N2\ using \_subset ground.subset_entailed by auto next fix N1 N2 assume N1_entails_C: \\C \ N2. N1 \\ {C}\ show \N1 \\ N2\ using ground.all_formulas_entailed N1_entails_C by (smt UN_E UN_I ground.entail_set_all_formulas singletonI) next fix N1 N2 N3 assume \N1 \\ N2\ and \N2 \\ N3\ then show \N1 \\ N3\ using ground.entails_trans by blast qed end subsection \Strong Standard Lifting\ (* rmk:strong-standard-lifting *) locale strong_standard_lifting = inference_system Inf_F + ground: calculus_with_red_crit Bot_G Inf_G entails_G Red_Inf_G Red_F_G for Bot_F :: \'f set\ and Inf_F :: \'f inference set\ and Bot_G :: \'g set\ and Inf_G :: \'g inference set\ and entails_G :: \'g set \ 'g set \ bool\ (infix "\G" 50) and Red_Inf_G :: \'g set \ 'g inference set\ and Red_F_G :: \'g set \ 'g set\ + fixes \_F :: \'f \ 'g set\ and \_Inf :: \'f inference \ 'g inference set option\ assumes Bot_F_not_empty: "Bot_F \ {}" and Bot_map_not_empty: \B \ Bot_F \ \_F B \ {}\ and Bot_map: \B \ Bot_F \ \_F B \ Bot_G\ and Bot_cond: \\_F C \ Bot_G \ {} \ C \ Bot_F\ and strong_inf_map: \\ \ Inf_F \ \_Inf \ \ None \ concl_of ` (the (\_Inf \)) \ (\_F (concl_of \))\ and inf_map_in_Inf: \\ \ Inf_F \ \_Inf \ \ None \ the (\_Inf \) \ Inf_G\ begin sublocale standard_lifting Bot_F Inf_F Bot_G Inf_G "(\G)" Red_Inf_G Red_F_G \_F \_Inf proof show "Bot_F \ {}" using Bot_F_not_empty . next fix B assume b_in: "B \ Bot_F" show "\_F B \ {}" using Bot_map_not_empty[OF b_in] . next fix B assume b_in: "B \ Bot_F" show "\_F B \ Bot_G" using Bot_map[OF b_in] . next show "\C. \_F C \ Bot_G \ {} \ C \ Bot_F" using Bot_cond . next fix \ assume i_in: "\ \ Inf_F" and some_g: "\_Inf \ \ None" show "the (\_Inf \) \ Red_Inf_G (\_F (concl_of \))" proof fix \G assume ig_in1: "\G \ the (\_Inf \)" then have ig_in2: "\G \ Inf_G" using inf_map_in_Inf[OF i_in some_g] by blast show "\G \ Red_Inf_G (\_F (concl_of \))" using strong_inf_map[OF i_in some_g] ground.Red_Inf_of_Inf_to_N[OF ig_in2] ig_in1 by blast qed qed end subsection \Lifting with a Family of Well-founded Orderings\ locale lifting_with_wf_ordering_family = standard_lifting Bot_F Inf_F Bot_G Inf_G entails_G Red_Inf_G Red_F_G \_F \_Inf for Bot_F :: \'f set\ and Inf_F :: \'f inference set\ and Bot_G :: \'g set\ and entails_G :: \'g set \ 'g set \ bool\ (infix "\G" 50) and Inf_G :: \'g inference set\ and Red_Inf_G :: \'g set \ 'g inference set\ and Red_F_G :: \'g set \ 'g set\ and \_F :: "'f \ 'g set" and \_Inf :: "'f inference \ 'g inference set option" + fixes Prec_F_g :: \'g \ 'f \ 'f \ bool\ assumes all_wf: "minimal_element (Prec_F_g g) UNIV" begin definition Red_Inf_\ :: "'f set \ 'f inference set" where \Red_Inf_\ N = {\ \ Inf_F. (\_Inf \ \ None \ the (\_Inf \) \ Red_Inf_G (\_set N)) \ (\_Inf \ = None \ \_F (concl_of \) \ \_set N \ Red_F_G (\_set N))}\ definition Red_F_\ :: "'f set \ 'f set" where \Red_F_\ N = {C. \D \ \_F C. D \ Red_F_G (\_set N) \ (\E \ N. Prec_F_g D E C \ D \ \_F E)}\ lemma Prec_trans: assumes \Prec_F_g D A B\ and \Prec_F_g D B C\ shows \Prec_F_g D A C\ using minimal_element.po assms unfolding po_on_def transp_on_def by (smt UNIV_I all_wf) lemma prop_nested_in_set: "D \ P C \ C \ {C. \D \ P C. A D \ B C D} \ A D \ B C D" by blast (* lem:wolog-C'-nonredundant *) lemma Red_F_\_equiv_def: \Red_F_\ N = {C. \Di \ \_F C. Di \ Red_F_G (\_set N) \ (\E \ (N - Red_F_\ N). Prec_F_g Di E C \ Di \ \_F E)}\ proof (rule; clarsimp) fix C D assume C_in: \C \ Red_F_\ N\ and D_in: \D \ \_F C\ and not_sec_case: \\E \ N - Red_F_\ N. Prec_F_g D E C \ D \ \_F E\ have C_in_unfolded: "C \ {C. \Di \ \_F C. Di \ Red_F_G (\_set N) \ (\E\N. Prec_F_g Di E C \ Di \ \_F E)}" using C_in unfolding Red_F_\_def . have neg_not_sec_case: \\ (\E\N - Red_F_\ N. Prec_F_g D E C \ D \ \_F E)\ using not_sec_case by clarsimp have unfol_C_D: \D \ Red_F_G (\_set N) \ (\E\N. Prec_F_g D E C \ D \ \_F E)\ using prop_nested_in_set[of D \_F C "\x. x \ Red_F_G (\ (\_F ` N))" "\x y. \E \ N. Prec_F_g y E x \ y \ \_F E", OF D_in C_in_unfolded] by blast show \D \ Red_F_G (\_set N)\ proof (rule ccontr) assume contrad: \D \ Red_F_G (\_set N)\ have non_empty: \\E\N. Prec_F_g D E C \ D \ \_F E\ using contrad unfol_C_D by auto define B where \B = {E \ N. Prec_F_g D E C \ D \ \_F E}\ then have B_non_empty: \B \ {}\ using non_empty by auto interpret minimal_element "Prec_F_g D" UNIV using all_wf[of D] . obtain F :: 'f where F: \F = min_elt B\ by auto then have D_in_F: \D \ \_F F\ unfolding B_def using non_empty by (smt Sup_UNIV Sup_upper UNIV_I contra_subsetD empty_iff empty_subsetI mem_Collect_eq min_elt_mem unfol_C_D) have F_prec: \Prec_F_g D F C\ using F min_elt_mem[of B, OF _ B_non_empty] unfolding B_def by auto have F_not_in: \F \ Red_F_\ N\ proof assume F_in: \F \ Red_F_\ N\ have unfol_F_D: \D \ Red_F_G (\_set N) \ (\G\N. Prec_F_g D G F \ D \ \_F G)\ using F_in D_in_F unfolding Red_F_\_def by auto then have \\G\N. Prec_F_g D G F \ D \ \_F G\ using contrad D_in unfolding Red_F_\_def by auto then obtain G where G_in: \G \ N\ and G_prec: \Prec_F_g D G F\ and G_map: \D \ \_F G\ by auto have \Prec_F_g D G C\ using G_prec F_prec Prec_trans by blast then have \G \ B\ unfolding B_def using G_in G_map by auto then show \False\ using F G_prec min_elt_minimal[of B G, OF _ B_non_empty] by auto qed have \F \ N\ using F by (metis B_def B_non_empty mem_Collect_eq min_elt_mem top_greatest) then have \F \ N - Red_F_\ N\ using F_not_in by auto then show \False\ using D_in_F neg_not_sec_case F_prec by blast qed next fix C assume only_if: \\D\\_F C. D \ Red_F_G (\_set N) \ (\E\N - Red_F_\ N. Prec_F_g D E C \ D \ \_F E)\ show \C \ Red_F_\ N\ unfolding Red_F_\_def using only_if by auto qed (* lem:lifting-main-technical *) lemma not_red_map_in_map_not_red: \\_set N - Red_F_G (\_set N) \ \_set (N - Red_F_\ N)\ proof fix D assume D_hyp: \D \ \_set N - Red_F_G (\_set N)\ interpret minimal_element "Prec_F_g D" UNIV using all_wf[of D] . have D_in: \D \ \_set N\ using D_hyp by blast have D_not_in: \D \ Red_F_G (\_set N)\ using D_hyp by blast have exist_C: \\C. C \ N \ D \ \_F C\ using D_in by auto define B where \B = {C \ N. D \ \_F C}\ obtain C where C: \C = min_elt B\ by auto have C_in_N: \C \ N\ using exist_C by (metis B_def C empty_iff mem_Collect_eq min_elt_mem top_greatest) have D_in_C: \D \ \_F C\ using exist_C by (metis B_def C empty_iff mem_Collect_eq min_elt_mem top_greatest) have C_not_in: \C \ Red_F_\ N\ proof assume C_in: \C \ Red_F_\ N\ have \D \ Red_F_G (\_set N) \ (\E\N. Prec_F_g D E C \ D \ \_F E)\ using C_in D_in_C unfolding Red_F_\_def by auto then show \False\ proof assume \D \ Red_F_G (\_set N)\ then show \False\ using D_not_in by simp next assume \\E\N. Prec_F_g D E C \ D \ \_F E\ then show \False\ using C by (metis (no_types, lifting) B_def UNIV_I empty_iff mem_Collect_eq min_elt_minimal top_greatest) qed qed show \D \ \_set (N - Red_F_\ N)\ using D_in_C C_not_in C_in_N by blast qed (* lem:nonredundant-entails-redundant *) lemma Red_F_Bot_F: \B \ Bot_F \ N \\ {B} \ N - Red_F_\ N \\ {B}\ proof - fix B N assume B_in: \B \ Bot_F\ and N_entails: \N \\ {B}\ then have to_bot: \\_set N - Red_F_G (\_set N) \G \_F B\ using ground.Red_F_Bot Bot_map by (smt cSup_singleton ground.entail_set_all_formulas image_insert image_is_empty subsetCE) have from_f: \\_set (N - Red_F_\ N) \G \_set N - Red_F_G (\_set N)\ using ground.subset_entailed[OF not_red_map_in_map_not_red] by blast then have \\_set (N - Red_F_\ N) \G \_F B\ using to_bot ground.entails_trans by blast then show \N - Red_F_\ N \\ {B}\ using Bot_map by simp qed (* lem:redundancy-monotonic-addition 1/2 *) lemma Red_F_of_subset_F: \N \ N' \ Red_F_\ N \ Red_F_\ N'\ using ground.Red_F_of_subset unfolding Red_F_\_def by clarsimp (meson \_subset subsetD) (* lem:redundancy-monotonic-addition 2/2 *) lemma Red_Inf_of_subset_F: \N \ N' \ Red_Inf_\ N \ Red_Inf_\ N'\ using Collect_mono \_subset subset_iff ground.Red_Inf_of_subset unfolding Red_Inf_\_def by (smt ground.Red_F_of_subset Un_iff) (* lem:redundancy-monotonic-deletion-forms *) lemma Red_F_of_Red_F_subset_F: \N' \ Red_F_\ N \ Red_F_\ N \ Red_F_\ (N - N')\ proof fix N N' C assume N'_in_Red_F_N: \N' \ Red_F_\ N\ and C_in_red_F_N: \C \ Red_F_\ N\ have lem8: \\D \ \_F C. D \ Red_F_G (\_set N) \ (\E \ (N - Red_F_\ N). Prec_F_g D E C \ D \ \_F E)\ using Red_F_\_equiv_def C_in_red_F_N by blast show \C \ Red_F_\ (N - N')\ unfolding Red_F_\_def proof (rule,rule) fix D assume \D \ \_F C\ then have \D \ Red_F_G (\_set N) \ (\E \ (N - Red_F_\ N). Prec_F_g D E C \ D \ \_F E)\ using lem8 by auto then show \D \ Red_F_G (\_set (N - N')) \ (\E\N - N'. Prec_F_g D E C \ D \ \_F E)\ proof assume \D \ Red_F_G (\_set N)\ then have \D \ Red_F_G (\_set N - Red_F_G (\_set N))\ using ground.Red_F_of_Red_F_subset[of "Red_F_G (\_set N)" "\_set N"] by auto then have \D \ Red_F_G (\_set (N - Red_F_\ N))\ using ground.Red_F_of_subset[OF not_red_map_in_map_not_red[of N]] by auto then have \D \ Red_F_G (\_set (N - N'))\ using N'_in_Red_F_N \_subset[of "N - Red_F_\ N" "N - N'"] by (smt DiffE DiffI ground.Red_F_of_subset subsetCE subsetI) then show ?thesis by blast next assume \\E\N - Red_F_\ N. Prec_F_g D E C \ D \ \_F E\ then obtain E where E_in: \E\N - Red_F_\ N\ and E_prec_C: \Prec_F_g D E C\ and D_in: \D \ \_F E\ by auto have \E \ N - N'\ using E_in N'_in_Red_F_N by blast then show ?thesis using E_prec_C D_in by blast qed qed qed (* lem:redundancy-monotonic-deletion-infs *) lemma Red_Inf_of_Red_F_subset_F: \N' \ Red_F_\ N \ Red_Inf_\ N \ Red_Inf_\ (N - N') \ proof fix N N' \ assume N'_in_Red_F_N: \N' \ Red_F_\ N\ and i_in_Red_Inf_N: \\ \ Red_Inf_\ N\ have i_in: \\ \ Inf_F\ using i_in_Red_Inf_N unfolding Red_Inf_\_def by blast { assume not_none: "\_Inf \ \ None" have \\\' \ the (\_Inf \). \' \ Red_Inf_G (\_set N)\ using not_none i_in_Red_Inf_N unfolding Red_Inf_\_def by auto then have \\\' \ the (\_Inf \). \' \ Red_Inf_G (\_set N - Red_F_G (\_set N))\ using not_none ground.Red_Inf_of_Red_F_subset by blast then have ip_in_Red_Inf_G: \\\' \ the (\_Inf \). \' \ Red_Inf_G (\_set (N - Red_F_\ N))\ using not_none ground.Red_Inf_of_subset[OF not_red_map_in_map_not_red[of N]] by auto then have not_none_in: \\\' \ the (\_Inf \). \' \ Red_Inf_G (\_set (N - N'))\ using not_none N'_in_Red_F_N by (meson Diff_mono ground.Red_Inf_of_subset \_subset subset_iff subset_refl) then have "the (\_Inf \) \ Red_Inf_G (\_set (N - N'))" by blast } moreover { assume none: "\_Inf \ = None" have ground_concl_subs: "\_F (concl_of \) \ (\_set N \ Red_F_G (\_set N))" using none i_in_Red_Inf_N unfolding Red_Inf_\_def by blast then have d_in_imp12: "D \ \_F (concl_of \) \ D \ \_set N - Red_F_G (\_set N) \ D \ Red_F_G (\_set N)" by blast have d_in_imp1: "D \ \_set N - Red_F_G (\_set N) \ D \ \_set (N - N')" using not_red_map_in_map_not_red N'_in_Red_F_N by blast have d_in_imp_d_in: "D \ Red_F_G (\_set N) \ D \ Red_F_G (\_set N - Red_F_G (\_set N))" using ground.Red_F_of_Red_F_subset[of "Red_F_G (\_set N)" "\_set N"] by blast have g_subs1: "\_set N - Red_F_G (\_set N) \ \_set (N - Red_F_\ N)" using not_red_map_in_map_not_red unfolding Red_F_\_def by auto have g_subs2: "\_set (N - Red_F_\ N) \ \_set (N - N')" using N'_in_Red_F_N by blast have d_in_imp2: "D \ Red_F_G (\_set N) \ D \ Red_F_G (\_set (N - N'))" using ground.Red_F_of_subset ground.Red_F_of_subset[OF g_subs1] ground.Red_F_of_subset[OF g_subs2] d_in_imp_d_in by blast have "\_F (concl_of \) \ (\_set (N - N') \ Red_F_G (\_set (N - N')))" using d_in_imp12 d_in_imp1 d_in_imp2 by (smt ground.Red_F_of_Red_F_subset ground.Red_F_of_subset UnCI UnE Un_Diff_cancel2 ground_concl_subs g_subs1 g_subs2 subset_iff) } ultimately show \\ \ Red_Inf_\ (N - N')\ using i_in unfolding Red_Inf_\_def by auto qed (* lem:concl-contained-implies-red-inf *) lemma Red_Inf_of_Inf_to_N_F: assumes i_in: \\ \ Inf_F\ and concl_i_in: \concl_of \ \ N\ shows \\ \ Red_Inf_\ N \ proof - have \\ \ Inf_F \ \_Inf \ \ None \ the (\_Inf \) \ Red_Inf_G (\_F (concl_of \))\ using inf_map by simp moreover have \Red_Inf_G (\_F (concl_of \)) \ Red_Inf_G (\_set N)\ using concl_i_in ground.Red_Inf_of_subset by blast moreover have "\ \ Inf_F \ \_Inf \ = None \ concl_of \ \ N \ \_F (concl_of \) \ \_set N" by blast ultimately show ?thesis using i_in concl_i_in unfolding Red_Inf_\_def by auto qed (* thm:FRedsqsubset-is-red-crit and also thm:lifted-red-crit if ordering empty *) sublocale calculus_with_red_crit Bot_F Inf_F entails_\ Red_Inf_\ Red_F_\ proof fix B N N' \ show \Red_Inf_\ N \ Inf_F\ unfolding Red_Inf_\_def by blast show \B \ Bot_F \ N \\ {B} \ N - Red_F_\ N \\ {B}\ using Red_F_Bot_F by simp show \N \ N' \ Red_F_\ N \ Red_F_\ N'\ using Red_F_of_subset_F by simp show \N \ N' \ Red_Inf_\ N \ Red_Inf_\ N'\ using Red_Inf_of_subset_F by simp show \N' \ Red_F_\ N \ Red_F_\ N \ Red_F_\ (N - N')\ using Red_F_of_Red_F_subset_F by simp show \N' \ Red_F_\ N \ Red_Inf_\ N \ Red_Inf_\ (N - N')\ using Red_Inf_of_Red_F_subset_F by simp show \\ \ Inf_F \ concl_of \ \ N \ \ \ Red_Inf_\ N\ using Red_Inf_of_Inf_to_N_F by simp qed lemma grounded_inf_in_ground_inf: "\ \ Inf_F \ \_Inf \ \ None \ the (\_Inf \) \ Inf_G" using inf_map ground.Red_Inf_to_Inf by blast abbreviation ground_Inf_redundant :: "'f set \ bool" where "ground_Inf_redundant N \ ground.Inf_from (\_set N) \ {\. \\'\ Inf_from N. \_Inf \' \ None \ \ \ the (\_Inf \')} \ Red_Inf_G (\_set N)" lemma sat_inf_imp_ground_red: assumes "saturated N" and "\' \ Inf_from N" and "\_Inf \' \ None \ \ \ the (\_Inf \')" shows "\ \ Red_Inf_G (\_set N)" using assms Red_Inf_\_def unfolding saturated_def by auto (* lem:sat-wrt-finf *) lemma sat_imp_ground_sat: "saturated N \ ground_Inf_redundant N \ ground.saturated (\_set N)" unfolding ground.saturated_def using sat_inf_imp_ground_red by auto (* thm:finf-complete *) theorem stat_ref_comp_to_non_ground: assumes stat_ref_G: "static_refutational_complete_calculus Bot_G Inf_G entails_G Red_Inf_G Red_F_G" and sat_n_imp: "\N. saturated N \ ground_Inf_redundant N" shows "static_refutational_complete_calculus Bot_F Inf_F entails_\ Red_Inf_\ Red_F_\" proof fix B N assume b_in: "B \ Bot_F" and sat_n: "saturated N" and n_entails_bot: "N \\ {B}" have ground_n_entails: "\_set N \G \_F B" using n_entails_bot by simp then obtain BG where bg_in1: "BG \ \_F B" using Bot_map_not_empty[OF b_in] by blast then have bg_in: "BG \ Bot_G" using Bot_map[OF b_in] by blast have ground_n_entails_bot: "\_set N \G {BG}" using ground_n_entails bg_in1 ground.entail_set_all_formulas by blast have "ground.Inf_from (\_set N) \ {\. \\'\ Inf_from N. \_Inf \' \ None \ \ \ the (\_Inf \')} \ Red_Inf_G (\_set N)" using sat_n_imp[OF sat_n] . have "ground.saturated (\_set N)" using sat_imp_ground_sat[OF sat_n sat_n_imp[OF sat_n]] . then have "\BG'\Bot_G. BG' \ (\_set N)" using stat_ref_G ground.calculus_with_red_crit_axioms bg_in ground_n_entails_bot unfolding static_refutational_complete_calculus_def static_refutational_complete_calculus_axioms_def by blast then show "\B'\ Bot_F. B' \ N" using bg_in Bot_cond Bot_map_not_empty Bot_cond by blast qed end lemma wf_empty_rel: "minimal_element (\_ _. False) UNIV" by (simp add: minimal_element.intro po_on_def transp_onI wfp_on_imp_irreflp_on) lemma any_to_empty_order_lifting: "lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F \_Inf Prec_F_g \ lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F \_Inf (\g C C'. False)" proof - fix Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F \_Inf Prec_F_g assume lift: "lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F \_Inf Prec_F_g" then interpret lift_g: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F \_Inf Prec_F_g by auto show "lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F \_Inf (\g C C'. False)" by (simp add: wf_empty_rel lift_g.standard_lifting_axioms lifting_with_wf_ordering_family_axioms.intro lifting_with_wf_ordering_family_def) qed +lemma po_on_empty_rel[simp]: "po_on (\_ _. False) UNIV" + unfolding po_on_def irreflp_on_def transp_on_def by auto + locale lifting_equivalence_with_empty_order = any_order_lifting: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F \_Inf Prec_F_g + empty_order_lifting: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G entails_G Inf_G Red_Inf_G Red_F_G \_F \_Inf "\g C C'. False" for \_F :: \'f \ 'g set\ and \_Inf :: \'f inference \ 'g inference set option\ and Bot_F :: \'f set\ and Inf_F :: \'f inference set\ and Bot_G :: \'g set\ and Inf_G :: \'g inference set\ and entails_G :: \'g set \ 'g set \ bool\ (infix "\G" 50) and Red_Inf_G :: \'g set \ 'g inference set\ and Red_F_G :: \'g set \ 'g set\ and Prec_F_g :: \'g \ 'f \ 'f \ bool\ sublocale lifting_with_wf_ordering_family \ lifting_equivalence_with_empty_order -proof - show "po_on (\C C'. False) UNIV" - unfolding po_on_def by (simp add: transp_onI wfp_on_imp_irreflp_on) - show "wfp_on (\C C'. False) UNIV" - unfolding wfp_on_def by simp -qed + by unfold_locales simp+ context lifting_equivalence_with_empty_order begin (* lem:saturation-indep-of-sqsubset *) lemma saturated_empty_order_equiv_saturated: "any_order_lifting.saturated N = empty_order_lifting.saturated N" by (rule refl) (* lem:static-ref-compl-indep-of-sqsubset *) lemma static_empty_order_equiv_static: "static_refutational_complete_calculus Bot_F Inf_F any_order_lifting.entails_\ empty_order_lifting.Red_Inf_\ empty_order_lifting.Red_F_\ = static_refutational_complete_calculus Bot_F Inf_F any_order_lifting.entails_\ any_order_lifting.Red_Inf_\ any_order_lifting.Red_F_\" unfolding static_refutational_complete_calculus_def by (rule iffI) (standard,(standard)[],simp)+ (* thm:FRedsqsubset-is-dyn-ref-compl *) theorem static_to_dynamic: "static_refutational_complete_calculus Bot_F Inf_F any_order_lifting.entails_\ empty_order_lifting.Red_Inf_\ empty_order_lifting.Red_F_\ = dynamic_refutational_complete_calculus Bot_F Inf_F any_order_lifting.entails_\ any_order_lifting.Red_Inf_\ any_order_lifting.Red_F_\ " using any_order_lifting.dyn_equiv_stat static_empty_order_equiv_static by blast end subsection \Lifting with a Family of Redundancy Criteria\ locale standard_lifting_with_red_crit_family = inference_system Inf_F + ground: calculus_family_with_red_crit_family Bot_G Q Inf_G_q entails_q Red_Inf_q Red_F_q for Inf_F :: "'f inference set" and Bot_G :: "'g set" and Q :: "'q set" and Inf_G_q :: \'q \ 'g inference set\ and entails_q :: "'q \ 'g set \ 'g set \ bool" and Red_Inf_q :: "'q \ 'g set \ 'g inference set" and Red_F_q :: "'q \ 'g set \ 'g set" + fixes Bot_F :: "'f set" and \_F_q :: "'q \ 'f \ 'g set" and \_Inf_q :: "'q \ 'f inference \ 'g inference set option" and Prec_F_g :: "'g \ 'f \ 'f \ bool" assumes standard_lifting_family: "\q \ Q. lifting_with_wf_ordering_family Bot_F Inf_F Bot_G (entails_q q) (Inf_G_q q) (Red_Inf_q q) (Red_F_q q) (\_F_q q) (\_Inf_q q) Prec_F_g" begin abbreviation \_set_q :: "'q \ 'f set \ 'g set" where "\_set_q q N \ \ (\_F_q q ` N)" definition Red_Inf_\_q :: "'q \ 'f set \ 'f inference set" where "Red_Inf_\_q q N = {\ \ Inf_F. (\_Inf_q q \ \ None \ the (\_Inf_q q \) \ Red_Inf_q q (\_set_q q N)) \ (\_Inf_q q \ = None \ \_F_q q (concl_of \) \ (\_set_q q N \ Red_F_q q (\_set_q q N)))}" definition Red_F_\_empty_q :: "'q \ 'f set \ 'f set" where "Red_F_\_empty_q q N = {C. \D \ \_F_q q C. D \ Red_F_q q (\_set_q q N)}" definition Red_F_\_q_g :: "'q \ 'f set \ 'f set" where "Red_F_\_q_g q N = {C. \D \ \_F_q q C. D \ Red_F_q q (\_set_q q N) \ (\E \ N. Prec_F_g D E C \ D \ \_F_q q E)}" abbreviation entails_\_q :: "'q \ 'f set \ 'f set \ bool" where "entails_\_q q N1 N2 \ entails_q q (\_set_q q N1) (\_set_q q N2)" lemma red_crit_lifting_family: assumes q_in: "q \ Q" shows "calculus_with_red_crit Bot_F Inf_F (entails_\_q q) (Red_Inf_\_q q) (Red_F_\_q_g q)" proof - interpret wf_lift: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G "entails_q q" "Inf_G_q q" "Red_Inf_q q" "Red_F_q q" "\_F_q q" "\_Inf_q q" Prec_F_g using standard_lifting_family q_in by metis have "Red_Inf_\_q q = wf_lift.Red_Inf_\" unfolding Red_Inf_\_q_def wf_lift.Red_Inf_\_def by blast moreover have "Red_F_\_q_g q = wf_lift.Red_F_\" unfolding Red_F_\_q_g_def wf_lift.Red_F_\_def by blast ultimately show ?thesis using wf_lift.calculus_with_red_crit_axioms by simp qed lemma red_crit_lifting_family_empty_ord: assumes q_in: "q \ Q" shows "calculus_with_red_crit Bot_F Inf_F (entails_\_q q) (Red_Inf_\_q q) (Red_F_\_empty_q q)" proof - interpret wf_lift: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G "entails_q q" "Inf_G_q q" "Red_Inf_q q" "Red_F_q q" "\_F_q q" "\_Inf_q q" Prec_F_g using standard_lifting_family q_in by metis have "Red_Inf_\_q q = wf_lift.Red_Inf_\" unfolding Red_Inf_\_q_def wf_lift.Red_Inf_\_def by blast moreover have "Red_F_\_empty_q q = wf_lift.empty_order_lifting.Red_F_\" unfolding Red_F_\_empty_q_def wf_lift.empty_order_lifting.Red_F_\_def by blast ultimately show ?thesis using wf_lift.empty_order_lifting.calculus_with_red_crit_axioms by simp qed sublocale consequence_relation_family Bot_F Q entails_\_q proof (unfold_locales; (intro ballI)?) show "Q \ {}" by (rule ground.Q_nonempty) next fix qi assume qi_in: "qi \ Q" interpret lift: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G "entails_q qi" "Inf_G_q qi" "Red_Inf_q qi" "Red_F_q qi" "\_F_q qi" "\_Inf_q qi" Prec_F_g using qi_in by (metis standard_lifting_family) show "consequence_relation Bot_F (entails_\_q qi)" by unfold_locales qed sublocale calculus_with_red_crit_family Bot_F Inf_F Q entails_\_q Red_Inf_\_q Red_F_\_q_g by unfold_locales (auto simp: Q_nonempty red_crit_lifting_family) abbreviation entails_\_Q :: "'f set \ 'f set \ bool" (infix "\\\" 50) where "(\\\) \ entails_Q" abbreviation Red_Inf_\_Q :: "'f set \ 'f inference set" where "Red_Inf_\_Q \ Red_Inf_Q" abbreviation Red_F_\_Q :: "'f set \ 'f set" where "Red_F_\_Q \ Red_F_Q" lemmas entails_\_Q_def = entails_Q_def lemmas Red_Inf_\_Q_def = Red_Inf_Q_def lemmas Red_F_\_Q_def = Red_F_Q_def sublocale empty_ord: calculus_with_red_crit_family Bot_F Inf_F Q entails_\_q Red_Inf_\_q Red_F_\_empty_q by unfold_locales (auto simp: Q_nonempty red_crit_lifting_family_empty_ord) abbreviation Red_F_\_empty :: "'f set \ 'f set" where "Red_F_\_empty \ empty_ord.Red_F_Q" lemmas Red_F_\_empty_def = empty_ord.Red_F_Q_def lemma sat_inf_imp_ground_red_fam_inter: assumes sat_n: "saturated N" and i'_in: "\' \ Inf_from N" and q_in: "q \ Q" and grounding: "\_Inf_q q \' \ None \ \ \ the (\_Inf_q q \')" shows "\ \ Red_Inf_q q (\_set_q q N)" proof - have "\' \ Red_Inf_\_q q N" using sat_n i'_in q_in all_red_crit calculus_with_red_crit.saturated_def sat_int_to_sat_q by blast then have "the (\_Inf_q q \') \ Red_Inf_q q (\_set_q q N)" by (simp add: Red_Inf_\_q_def grounding) then show ?thesis using grounding by blast qed abbreviation ground_Inf_redundant :: "'q \ 'f set \ bool" where "ground_Inf_redundant q N \ ground.Inf_from_q q (\_set_q q N) \ {\. \\'\ Inf_from N. \_Inf_q q \' \ None \ \ \ the (\_Inf_q q \')} \ Red_Inf_q q (\_set_q q N)" abbreviation ground_saturated :: "'q \ 'f set \ bool" where "ground_saturated q N \ ground.Inf_from_q q (\_set_q q N) \ Red_Inf_q q (\_set_q q N)" lemma sat_imp_ground_sat_fam_inter: "saturated N \ q \ Q \ ground_Inf_redundant q N \ ground_saturated q N" using sat_inf_imp_ground_red_fam_inter by auto (* thm:intersect-finf-complete *) theorem stat_ref_comp_to_non_ground_fam_inter: assumes stat_ref_G: "\q \ Q. static_refutational_complete_calculus Bot_G (Inf_G_q q) (entails_q q) (Red_Inf_q q) (Red_F_q q)" and sat_n_imp: "\N. saturated N \ \q \ Q. ground_Inf_redundant q N" shows "static_refutational_complete_calculus Bot_F Inf_F entails_\_Q Red_Inf_\_Q Red_F_\_empty" using empty_ord.calculus_with_red_crit_axioms unfolding static_refutational_complete_calculus_def static_refutational_complete_calculus_axioms_def proof (standard, clarify) fix B N assume b_in: "B \ Bot_F" and sat_n: "saturated N" and entails_bot: "N \\\ {B}" then obtain q where q_in: "q \ Q" and inf_subs: "ground.Inf_from_q q (\_set_q q N) \ {\. \\'\ Inf_from N. \_Inf_q q \' \ None \ \ \ the (\_Inf_q q \')} \ Red_Inf_q q (\_set_q q N)" using sat_n_imp[of N] by blast interpret q_calc: calculus_with_red_crit Bot_F Inf_F "entails_\_q q" "Red_Inf_\_q q" "Red_F_\_q_g q" using all_red_crit[rule_format, OF q_in] . have n_q_sat: "q_calc.saturated N" using q_in sat_int_to_sat_q sat_n by simp interpret lifted_q_calc: lifting_with_wf_ordering_family Bot_F Inf_F Bot_G "entails_q q" "Inf_G_q q" "Red_Inf_q q" "Red_F_q q" "\_F_q q" "\_Inf_q q" using q_in by (simp add: standard_lifting_family) have n_lift_sat: "lifted_q_calc.empty_order_lifting.saturated N" using n_q_sat unfolding Red_Inf_\_q_def lifted_q_calc.empty_order_lifting.Red_Inf_\_def lifted_q_calc.saturated_def q_calc.saturated_def by auto have ground_sat_n: "lifted_q_calc.ground.saturated (\_set_q q N)" by (rule lifted_q_calc.sat_imp_ground_sat[OF n_lift_sat]) (use n_lift_sat inf_subs ground.Inf_from_q_def in auto) have ground_n_entails_bot: "entails_\_q q N {B}" using q_in entails_bot unfolding entails_\_Q_def by simp interpret static_refutational_complete_calculus Bot_G "Inf_G_q q" "entails_q q" "Red_Inf_q q" "Red_F_q q" using stat_ref_G[rule_format, OF q_in] . obtain BG where bg_in: "BG \ \_F_q q B" using lifted_q_calc.Bot_map_not_empty[OF b_in] by blast then have "BG \ Bot_G" using lifted_q_calc.Bot_map[OF b_in] by blast then have "\BG'\Bot_G. BG' \ \_set_q q N" using ground_sat_n ground_n_entails_bot static_refutational_complete[of BG, OF _ ground_sat_n] bg_in lifted_q_calc.ground.entail_set_all_formulas[of "\_set_q q N" "\_set_q q {B}"] by simp then show "\B'\ Bot_F. B' \ N" using lifted_q_calc.Bot_cond by blast qed (* lem:intersect-saturation-indep-of-sqsubset *) lemma sat_eq_sat_empty_order: "saturated N = empty_ord.saturated N" by (rule refl) (* lem:intersect-static-ref-compl-indep-of-sqsubset *) lemma static_empty_ord_inter_equiv_static_inter: "static_refutational_complete_calculus Bot_F Inf_F entails_Q Red_Inf_Q Red_F_Q = static_refutational_complete_calculus Bot_F Inf_F entails_Q Red_Inf_Q Red_F_\_empty" unfolding static_refutational_complete_calculus_def by (simp add: empty_ord.calculus_with_red_crit_axioms calculus_with_red_crit_axioms) (* thm:intersect-static-ref-compl-is-dyn-ref-compl-with-order *) theorem stat_eq_dyn_ref_comp_fam_inter: "static_refutational_complete_calculus Bot_F Inf_F entails_Q Red_Inf_Q Red_F_\_empty = dynamic_refutational_complete_calculus Bot_F Inf_F entails_Q Red_Inf_Q Red_F_Q" using dyn_equiv_stat static_empty_ord_inter_equiv_static_inter by blast end end