diff --git a/thys/Functional_Ordered_Resolution_Prover/Weighted_FO_Ordered_Resolution_Prover.thy b/thys/Functional_Ordered_Resolution_Prover/Weighted_FO_Ordered_Resolution_Prover.thy --- a/thys/Functional_Ordered_Resolution_Prover/Weighted_FO_Ordered_Resolution_Prover.thy +++ b/thys/Functional_Ordered_Resolution_Prover/Weighted_FO_Ordered_Resolution_Prover.thy @@ -1,836 +1,836 @@ (* Title: A Fair Ordered Resolution Prover for First-Order Clauses with Weights Author: Anders Schlichtkrull , 2017 Author: Jasmin Blanchette , 2017 Maintainer: Anders Schlichtkrull *) section \A Fair Ordered Resolution Prover for First-Order Clauses with Weights\ text \ The \weighted_RP\ prover introduced below operates on finite multisets of clauses and organizes the multiset of processed clauses as a priority queue to ensure that inferences are performed in a fair manner, to guarantee completeness. \ theory Weighted_FO_Ordered_Resolution_Prover imports Ordered_Resolution_Prover.FO_Ordered_Resolution_Prover begin subsection \Prover\ type_synonym 'a wclause = "'a clause \ nat" type_synonym 'a wstate = "'a wclause multiset \ 'a wclause multiset \ 'a wclause multiset \ nat" fun state_of_wstate :: "'a wstate \ 'a state" where "state_of_wstate (N, P, Q, n) = (set_mset (image_mset fst N), set_mset (image_mset fst P), set_mset (image_mset fst Q))" locale weighted_FO_resolution_prover = FO_resolution_prover S subst_atm id_subst comp_subst renamings_apart atm_of_atms mgu less_atm 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" + fixes weight :: "'a clause \ nat \ nat" assumes weight_mono: "i < j \ weight (C, i) < weight (C, j)" begin abbreviation clss_of_wstate :: "'a wstate \ 'a clause set" where "clss_of_wstate St \ clss_of_state (state_of_wstate St)" abbreviation N_of_wstate :: "'a wstate \ 'a clause set" where "N_of_wstate St \ N_of_state (state_of_wstate St)" abbreviation P_of_wstate :: "'a wstate \ 'a clause set" where "P_of_wstate St \ P_of_state (state_of_wstate St)" abbreviation Q_of_wstate :: "'a wstate \ 'a clause set" where "Q_of_wstate St \ Q_of_state (state_of_wstate St)" fun wN_of_wstate :: "'a wstate \ 'a wclause multiset" where "wN_of_wstate (N, P, Q, n) = N" fun wP_of_wstate :: "'a wstate \ 'a wclause multiset" where "wP_of_wstate (N, P, Q, n) = P" fun wQ_of_wstate :: "'a wstate \ 'a wclause multiset" where "wQ_of_wstate (N, P, Q, n) = Q" fun n_of_wstate :: "'a wstate \ nat" where "n_of_wstate (N, P, Q, n) = n" lemma of_wstate_split[simp]: "(wN_of_wstate St, wP_of_wstate St, wQ_of_wstate St, n_of_wstate St) = St" by (cases St) auto abbreviation grounding_of_wstate :: "'a wstate \ 'a clause set" where "grounding_of_wstate St \ grounding_of_state (state_of_wstate St)" abbreviation Liminf_wstate :: "'a wstate llist \ 'a state" where "Liminf_wstate Sts \ Liminf_state (lmap state_of_wstate Sts)" lemma timestamp_le_weight: "n \ weight (C, n)" by (induct n, simp, metis weight_mono[of k "Suc k" for k] Suc_le_eq le_less le_trans) inductive weighted_RP :: "'a wstate \ 'a wstate \ bool" (infix "\\<^sub>w" 50) where tautology_deletion: "Neg A \# C \ Pos A \# C \ (N + {#(C, i)#}, P, Q, n) \\<^sub>w (N, P, Q, n)" | forward_subsumption: "D \# image_mset fst (P + Q) \ subsumes D C \ (N + {#(C, i)#}, P, Q, n) \\<^sub>w (N, P, Q, n)" | backward_subsumption_P: "D \# image_mset fst N \ C \# image_mset fst P \ strictly_subsumes D C \ (N, P, Q, n) \\<^sub>w (N, {#(E, k) \# P. E \ C#}, Q, n)" | backward_subsumption_Q: "D \# image_mset fst N \ strictly_subsumes D C \ (N, P, Q + {#(C, i)#}, n) \\<^sub>w (N, P, Q, n)" | forward_reduction: "D + {#L'#} \# image_mset fst (P + Q) \ - L = L' \l \ \ D \ \ \# C \ (N + {#(C + {#L#}, i)#}, P, Q, n) \\<^sub>w (N + {#(C, i)#}, P, Q, n)" | backward_reduction_P: "D + {#L'#} \# image_mset fst N \ - L = L' \l \ \ D \ \ \# C \ (\j. (C + {#L#}, j) \# P \ j \ i) \ (N, P + {#(C + {#L#}, i)#}, Q, n) \\<^sub>w (N, P + {#(C, i)#}, Q, n)" | backward_reduction_Q: "D + {#L'#} \# image_mset fst N \ - L = L' \l \ \ D \ \ \# C \ (N, P, Q + {#(C + {#L#}, i)#}, n) \\<^sub>w (N, P + {#(C, i)#}, Q, n)" | clause_processing: "(N + {#(C, i)#}, P, Q, n) \\<^sub>w (N, P + {#(C, i)#}, Q, n)" | inference_computation: "(\(D, j) \# P. weight (C, i) \ weight (D, j)) \ N = mset_set ((\D. (D, n)) ` concls_of (inference_system.inferences_between (ord_FO_\ S) (set_mset (image_mset fst Q)) C)) \ ({#}, P + {#(C, i)#}, Q, n) \\<^sub>w (N, {#(D, j) \# P. D \ C#}, Q + {#(C, i)#}, Suc n)" lemma weighted_RP_imp_RP: "St \\<^sub>w St' \ state_of_wstate St \ state_of_wstate St'" proof (induction rule: weighted_RP.induct) case (backward_subsumption_P D N C P Q n) show ?case by (rule arg_cong2[THEN iffD1, of _ _ _ _ "(\)", OF _ _ RP.backward_subsumption_P[of D "fst ` set_mset N" C "fst ` set_mset P - {C}" "fst ` set_mset Q"]]) (use backward_subsumption_P in auto) next case (inference_computation P C i N n Q) show ?case by (rule arg_cong2[THEN iffD1, of _ _ _ _ "(\)", OF _ _ RP.inference_computation[of "fst ` set_mset N" "fst ` set_mset Q" C "fst ` set_mset P - {C}"]], use inference_computation(2) finite_ord_FO_resolution_inferences_between in \auto simp: comp_def image_comp inference_system.inferences_between_def\) qed (use RP.intros in simp_all) lemma final_weighted_RP: "\ ({#}, {#}, Q, n) \\<^sub>w St" by (auto elim: weighted_RP.cases) context fixes Sts :: "'a wstate llist" assumes full_deriv: "full_chain (\\<^sub>w) Sts" and empty_P0: "P_of_wstate (lhd Sts) = {}" and empty_Q0: "Q_of_wstate (lhd Sts) = {}" begin lemma finite_Sts0: "finite (clss_of_wstate (lhd Sts))" by (cases "lhd Sts") auto lemmas deriv = full_chain_imp_chain[OF full_deriv] lemmas lhd_lmap_Sts = llist.map_sel(1)[OF chain_not_lnull[OF deriv]] lemma deriv_RP: "chain (\) (lmap state_of_wstate Sts)" using deriv weighted_RP_imp_RP by (metis chain_lmap) lemma finite_Sts0_RP: "finite (clss_of_state (lhd (lmap state_of_wstate Sts)))" using finite_Sts0 chain_length_pos[OF deriv] by auto lemma empty_P0_RP: "P_of_state (lhd (lmap state_of_wstate Sts)) = {}" using empty_P0 chain_length_pos[OF deriv] by auto lemma empty_Q0_RP: "Q_of_state (lhd (lmap state_of_wstate Sts)) = {}" using empty_Q0 chain_length_pos[OF deriv] by auto lemmas Sts_thms = deriv_RP finite_Sts0_RP empty_P0_RP empty_Q0_RP theorem weighted_RP_model: "St \\<^sub>w St' \ I \s grounding_of_wstate St' \ I \s grounding_of_wstate St" using RP_model Sts_thms weighted_RP_imp_RP by (simp only: comp_def) abbreviation S_gQ :: "'a clause \ 'a clause" where "S_gQ \ S_Q (lmap state_of_wstate Sts)" interpretation sq: selection S_gQ - unfolding S_Q_def[OF deriv_RP] using S_M_selects_subseteq S_M_selects_neg_lits selection_axioms + unfolding S_Q_def using S_M_selects_subseteq S_M_selects_neg_lits selection_axioms by unfold_locales auto interpretation gd: ground_resolution_with_selection S_gQ by unfold_locales interpretation src: standard_redundancy_criterion_reductive gd.ord_\ by unfold_locales interpretation src: standard_redundancy_criterion_counterex_reducing gd.ord_\ "ground_resolution_with_selection.INTERP S_gQ" by unfold_locales lemmas ord_\_saturated_upto_def = src.saturated_upto_def lemmas ord_\_saturated_upto_complete = src.saturated_upto_complete lemmas ord_\_contradiction_Rf = src.contradiction_Rf theorem weighted_RP_sound: assumes "{#} \ clss_of_state (Liminf_wstate Sts)" shows "\ satisfiable (grounding_of_wstate (lhd Sts))" by (rule RP_sound[OF deriv_RP assms, unfolded lhd_lmap_Sts]) abbreviation RP_filtered_measure :: "('a wclause \ bool) \ 'a wstate \ nat \ nat \ nat" where "RP_filtered_measure \ \p (N, P, Q, n). (sum_mset (image_mset (\(C, i). Suc (size C)) {#Di \# N + P + Q. p Di#}), size {#Di \# N. p Di#}, size {#Di \# P. p Di#})" abbreviation RP_combined_measure :: "nat \ 'a wstate \ nat \ (nat \ nat \ nat) \ (nat \ nat \ nat)" where "RP_combined_measure \ \w St. (w + 1 - n_of_wstate St, RP_filtered_measure (\(C, i). i \ w) St, RP_filtered_measure (\Ci. True) St)" abbreviation (input) RP_filtered_relation :: "((nat \ nat \ nat) \ (nat \ nat \ nat)) set" where "RP_filtered_relation \ natLess <*lex*> natLess <*lex*> natLess" abbreviation (input) RP_combined_relation :: "((nat \ ((nat \ nat \ nat) \ (nat \ nat \ nat))) \ (nat \ ((nat \ nat \ nat) \ (nat \ nat \ nat)))) set" where "RP_combined_relation \ natLess <*lex*> RP_filtered_relation <*lex*> RP_filtered_relation" abbreviation "(fst3 :: 'b * 'c * 'd \ 'b) \ fst" abbreviation "(snd3 :: 'b * 'c * 'd \ 'c) \ \x. fst (snd x)" abbreviation "(trd3 :: 'b * 'c * 'd \ 'd) \ \x. snd (snd x)" lemma wf_RP_filtered_relation: "wf RP_filtered_relation" and wf_RP_combined_relation: "wf RP_combined_relation" unfolding natLess_def using wf_less wf_mult by auto lemma multiset_sum_of_Suc_f_monotone: "N \# M \ (\x \# N. Suc (f x)) < (\x \# M. Suc (f x))" proof (induction N arbitrary: M) case empty then obtain y where "y \# M" by force then have "(\x \# M. 1) = (\x \# M - {#y#} + {#y#}. 1)" by auto also have "... = (\x \# M - {#y#}. 1) + (\x \# {#y#}. 1)" by (metis image_mset_union sum_mset.union) also have "... > (0 :: nat)" by auto finally have "0 < (\x \# M. Suc (f x))" by (fastforce intro: gr_zeroI) then show ?case using empty by auto next case (add x N) from this(2) have "(\y \# N. Suc (f y)) < (\y \# M - {#x#}. Suc (f y))" using add(1)[of "M - {#x#}"] by (simp add: insert_union_subset_iff) moreover have "add_mset x (remove1_mset x M) = M" by (meson add.prems add_mset_remove_trivial_If mset_subset_insertD) ultimately show ?case by (metis (no_types) add.commute add_less_cancel_right sum_mset.insert) qed lemma multiset_sum_monotone_f': assumes "CC \# DD" shows "(\(C, i) \# CC. Suc (f C)) < (\(C, i) \# DD. Suc (f C))" using multiset_sum_of_Suc_f_monotone[OF assms, of "f \ fst"] by (metis (mono_tags) comp_apply image_mset_cong2 split_beta) lemma filter_mset_strict_subset: assumes "x \# M" and "\ p x" shows "{#y \# M. p y#} \# M" proof - have subseteq: "{#E \# M. p E#} \# M" by auto have "count {#E \# M. p E#} x = 0" using assms by auto moreover have "0 < count M x" using assms by auto ultimately have lt_count: "count {#y \# M. p y#} x < count M x" by auto then show ?thesis using subseteq by (metis less_not_refl2 subset_mset.le_neq_trans) qed lemma weighted_RP_measure_decreasing_N: assumes "St \\<^sub>w St'" and "(C, l) \# wN_of_wstate St" shows "(RP_filtered_measure (\Ci. True) St', RP_filtered_measure (\Ci. True) St) \ RP_filtered_relation" using assms proof (induction rule: weighted_RP.induct) case (backward_subsumption_P D N C' P Q n) then obtain i' where "(C', i') \# P" by auto then have "{#(E, k) \# P. E \ C'#} \# P" using filter_mset_strict_subset[of "(C', i')" P "\X. \fst X = C'"] by (metis (mono_tags, lifting) filter_mset_cong fst_conv prod.case_eq_if) then have "(\(C, i) \# {#(E, k) \# P. E \ C'#}. Suc (size C)) < (\(C, i) \# P. Suc (size C))" using multiset_sum_monotone_f'[of "{#(E, k) \# P. E \ C'#}" P size] by metis then show ?case unfolding natLess_def by auto qed (auto simp: natLess_def) lemma weighted_RP_measure_decreasing_P: assumes "St \\<^sub>w St'" and "(C, i) \# wP_of_wstate St" shows "(RP_combined_measure (weight (C, i)) St', RP_combined_measure (weight (C, i)) St) \ RP_combined_relation" using assms proof (induction rule: weighted_RP.induct) case (backward_subsumption_P D N C' P Q n) define St where "St = (N, P, Q, n)" define P' where "P' = {#(E, k) \# P. E \ C'#}" define St' where "St' = (N, P', Q, n)" from backward_subsumption_P obtain i' where "(C', i') \# P" by auto then have P'_sub_P: "P' \# P" unfolding P'_def using filter_mset_strict_subset[of "(C', i')" P "\Dj. fst Dj \ C'"] by (metis (no_types, lifting) filter_mset_cong fst_conv prod.case_eq_if) have P'_subeq_P_filter: "{#(Ca, ia) \# P'. ia \ weight (C, i)#} \# {#(Ca, ia) \# P. ia \ weight (C, i)#}" using P'_sub_P by (auto intro: multiset_filter_mono) have "fst3 (RP_combined_measure (weight (C, i)) St') \ fst3 (RP_combined_measure (weight (C, i)) St)" unfolding St'_def St_def by auto moreover have "(\(C, i) \# {#(Ca, ia) \# P'. ia \ weight (C, i)#}. Suc (size C)) \ (\x \# {#(Ca, ia) \# P. ia \ weight (C, i)#}. case x of (C, i) \ Suc (size C))" using P'_subeq_P_filter by (rule sum_image_mset_mono) then have "fst3 (snd3 (RP_combined_measure (weight (C, i)) St')) \ fst3 (snd3 (RP_combined_measure (weight (C, i)) St))" unfolding St'_def St_def by auto moreover have "snd3 (snd3 (RP_combined_measure (weight (C, i)) St')) \ snd3 (snd3 (RP_combined_measure (weight (C, i)) St))" unfolding St'_def St_def by auto moreover from P'_subeq_P_filter have "size {#(Ca, ia) \# P'. ia \ weight (C, i)#} \ size {#(Ca, ia) \# P. ia \ weight (C, i)#}" by (simp add: size_mset_mono) then have "trd3 (snd3 (RP_combined_measure (weight (C, i)) St')) \ trd3 (snd3 (RP_combined_measure (weight (C, i)) St))" unfolding St'_def St_def unfolding fst_def snd_def by auto moreover from P'_sub_P have "(\(C, i) \# P'. Suc (size C)) < (\(C, i) \# P. Suc (size C))" using multiset_sum_monotone_f'[of "{#(E, k) \# P. E \ C'#}" P size] unfolding P'_def by metis then have "fst3 (trd3 (RP_combined_measure (weight (C, i)) St')) < fst3 (trd3 (RP_combined_measure (weight (C, i)) St))" unfolding P'_def St'_def St_def by auto ultimately show ?case unfolding natLess_def P'_def St'_def St_def by auto next case (inference_computation P C' i' N n Q) then show ?case proof (cases "n \ weight (C, i)") case True then have "weight (C, i) + 1 - n > weight (C, i) + 1 - Suc n" by auto then show ?thesis unfolding natLess_def by auto next case n_nle_w: False define St :: "'a wstate" where "St = ({#}, P + {#(C', i')#}, Q, n)" define St' :: "'a wstate" where "St' = (N, {#(D, j) \# P. D \ C'#}, Q + {#(C', i')#}, Suc n)" define concls :: "'a wclause set" where "concls = (\D. (D, n)) ` concls_of (inference_system.inferences_between (ord_FO_\ S) (fst ` set_mset Q) C')" have fin: "finite concls" unfolding concls_def using finite_ord_FO_resolution_inferences_between by auto have "{(D, ia) \ concls. ia \ weight (C, i)} = {}" unfolding concls_def using n_nle_w by auto then have "{#(D, ia) \# mset_set concls. ia \ weight (C, i)#} = {#}" using fin filter_mset_empty_if_finite_and_filter_set_empty[of concls] by auto then have n_low_weight_empty: "{#(D, ia) \# N. ia \ weight (C, i)#} = {#}" unfolding inference_computation unfolding concls_def by auto have "weight (C', i') \ weight (C, i)" using inference_computation by auto then have i'_le_w_Ci: "i' \ weight (C, i)" using timestamp_le_weight[of i' C'] by auto have subs: "{#(D, ia) \# N + {#(D, j) \# P. D \ C'#} + (Q + {#(C', i')#}). ia \ weight (C, i)#} \# {#(D, ia) \# {#} + (P + {#(C', i')#}) + Q. ia \ weight (C, i)#}" using n_low_weight_empty by (auto simp: multiset_filter_mono) have "fst3 (RP_combined_measure (weight (C, i)) St') \ fst3 (RP_combined_measure (weight (C, i)) St)" unfolding St'_def St_def by auto moreover have "fst (RP_filtered_measure ((\(D, ia). ia \ weight (C, i))) St') = (\(C, i) \# {#(D, ia) \# N + {#(D, j) \# P. D \ C'#} + (Q + {#(C', i')#}). ia \ weight (C, i)#}. Suc (size C))" unfolding St'_def by auto also have "... \ (\(C, i) \# {#(D, ia) \# {#} + (P + {#(C', i')#}) + Q. ia \ weight (C, i)#}. Suc (size C))" using subs sum_image_mset_mono by blast also have "... = fst (RP_filtered_measure (\(D, ia). ia \ weight (C, i)) St)" unfolding St_def by auto finally have "fst3 (snd3 (RP_combined_measure (weight (C, i)) St')) \ fst3 (snd3 (RP_combined_measure (weight (C, i)) St))" by auto moreover have "snd3 (snd3 (RP_combined_measure (weight (C, i)) St')) = snd3 (snd3 (RP_combined_measure (weight (C, i)) St))" unfolding St_def St'_def using n_low_weight_empty by auto moreover have "trd3 (snd3 (RP_combined_measure (weight (C, i)) St')) < trd3 (snd3 (RP_combined_measure (weight (C, i)) St))" unfolding St_def St'_def using i'_le_w_Ci by (simp add: le_imp_less_Suc multiset_filter_mono size_mset_mono) ultimately show ?thesis unfolding natLess_def St'_def St_def lex_prod_def by force qed qed (auto simp: natLess_def) lemma preserve_min_or_delete_completely: assumes "St \\<^sub>w St'" "(C, i) \# wP_of_wstate St" "\k. (C, k) \# wP_of_wstate St \ i \ k" shows "(C, i) \# wP_of_wstate St' \ (\j. (C, j) \# wP_of_wstate St')" using assms proof (induction rule: weighted_RP.induct) case (backward_reduction_P D L' N L \ C' P i' Q n) show ?case proof (cases "C = C' + {#L#}") case True_outer: True then have C_i_in: "(C, i) \# P + {#(C, i')#}" using backward_reduction_P by auto then have max: "\k. (C, k) \# P + {#(C, i')#} \ k \ i'" using backward_reduction_P unfolding True_outer[symmetric] by auto then have "count (P + {#(C, i')#}) (C, i') \ 1" by auto moreover { assume asm: "count (P + {#(C, i')#}) (C, i') = 1" then have nin_P: "(C, i') \# P" using not_in_iff by force have ?thesis proof (cases "(C, i) = (C, i')") case True then have "i = i'" by auto then have "\j. (C, j) \# P + {#(C, i')#} \ j = i'" using max backward_reduction_P(6) unfolding True_outer[symmetric] by force then show ?thesis using True_outer[symmetric] nin_P by auto next case False then show ?thesis using C_i_in by auto qed } moreover { assume "count (P + {#(C, i')#}) (C, i') > 1" then have ?thesis using C_i_in by auto } ultimately show ?thesis by (cases "count (P + {#(C, i')#}) (C, i') = 1") auto next case False then show ?thesis using backward_reduction_P by auto qed qed auto lemma preserve_min_P: assumes "St \\<^sub>w St'" "(C, j) \# wP_of_wstate St'" and "(C, i) \# wP_of_wstate St" and "\k. (C, k) \# wP_of_wstate St \ i \ k" shows "(C, i) \# wP_of_wstate St'" using assms preserve_min_or_delete_completely by blast lemma preserve_min_P_Sts: assumes "enat (Suc k) < llength Sts" and "(C, i) \# wP_of_wstate (lnth Sts k)" and "(C, j) \# wP_of_wstate (lnth Sts (Suc k))" and "\j. (C, j) \# wP_of_wstate (lnth Sts k) \ i \ j" shows "(C, i) \# wP_of_wstate (lnth Sts (Suc k))" using deriv assms chain_lnth_rel preserve_min_P by metis lemma in_lnth_in_Supremum_ldrop: assumes "i < llength xs" and "x \# (lnth xs i)" shows "x \ Sup_llist (lmap set_mset (ldrop (enat i) xs))" using assms by (metis (no_types) ldrop_eq_LConsD ldropn_0 llist.simps(13) contra_subsetD ldrop_enat ldropn_Suc_conv_ldropn lnth_0 lnth_lmap lnth_subset_Sup_llist) lemma persistent_wclause_in_P_if_persistent_clause_in_P: assumes "C \ Liminf_llist (lmap P_of_state (lmap state_of_wstate Sts))" shows "\i. (C, i) \ Liminf_llist (lmap (set_mset \ wP_of_wstate) Sts)" proof - obtain t_C where t_C_p: "enat t_C < llength Sts" "\t. t_C \ t \ t < llength Sts \ C \ P_of_state (state_of_wstate (lnth Sts t))" using assms unfolding Liminf_llist_def by auto then obtain i where i_p: "(C, i) \# wP_of_wstate (lnth Sts t_C)" using t_C_p by (cases "lnth Sts t_C") force have Ci_in_nth_wP: "\i. (C, i) \# wP_of_wstate (lnth Sts (t_C + t))" if "t_C + t < llength Sts" for t using that t_C_p(2)[of "t_C + _"] by (cases "lnth Sts (t_C + t)") force define in_Sup_wP :: "nat \ bool" where "in_Sup_wP = (\i. (C, i) \ Sup_llist (lmap (set_mset \ wP_of_wstate) (ldrop t_C Sts)))" have "in_Sup_wP i" using i_p assms(1) in_lnth_in_Supremum_ldrop[of t_C "lmap wP_of_wstate Sts" "(C, i)"] t_C_p by (simp add: in_Sup_wP_def llist.map_comp) then obtain j where j_p: "is_least in_Sup_wP j" unfolding in_Sup_wP_def[symmetric] using least_exists by metis then have "\i. (C, i) \ Sup_llist (lmap (set_mset \ wP_of_wstate) (ldrop t_C Sts)) \ j \ i" unfolding is_least_def in_Sup_wP_def using not_less by blast then have j_smallest: "\i t. enat (t_C + t) < llength Sts \ (C, i) \# wP_of_wstate (lnth Sts (t_C + t)) \ j \ i" unfolding comp_def by (smt add.commute ldrop_enat ldrop_eq_LConsD ldrop_ldrop ldropn_Suc_conv_ldropn plus_enat_simps(1) lnth_ldropn Sup_llist_def UN_I ldrop_lmap llength_lmap lnth_lmap mem_Collect_eq) from j_p have "\t_Cj. t_Cj < llength (ldrop (enat t_C) Sts) \ (C, j) \# wP_of_wstate (lnth (ldrop t_C Sts) t_Cj)" unfolding in_Sup_wP_def Sup_llist_def is_least_def by simp then obtain t_Cj where j_p: "(C,j) \# wP_of_wstate (lnth Sts (t_C + t_Cj))" "enat (t_C + t_Cj) < llength Sts" by (smt add.commute ldrop_enat ldrop_eq_LConsD ldrop_ldrop ldropn_Suc_conv_ldropn plus_enat_simps(1) lhd_ldropn) have Ci_stays: "t_C + t_Cj + t < llength Sts \ (C,j) \# wP_of_wstate (lnth Sts (t_C + t_Cj + t))" for t proof (induction t) case 0 then show ?case using j_p by (simp add: add.commute) next case (Suc t) have any_Ck_in_wP: "j \ k" if "(C, k) \# wP_of_wstate (lnth Sts (t_C + t_Cj + t))" for k using that j_p j_smallest Suc by (smt Suc_ile_eq add.commute add.left_commute add_Suc less_imp_le plus_enat_simps(1) the_enat.simps) from Suc have Cj_in_wP: "(C, j) \# wP_of_wstate (lnth Sts (t_C + t_Cj + t))" by (metis (no_types, hide_lams) Suc_ile_eq add.commute add_Suc_right less_imp_le) moreover have "C \ P_of_state (state_of_wstate (lnth Sts (Suc (t_C + t_Cj + t))))" using t_C_p(2) Suc.prems by auto then have "\k. (C, k) \# wP_of_wstate (lnth Sts (Suc (t_C + t_Cj + t)))" by (smt Suc.prems Ci_in_nth_wP add.commute add.left_commute add_Suc_right enat_ord_code(4)) ultimately have "(C, j) \# wP_of_wstate (lnth Sts (Suc (t_C + t_Cj + t)))" using preserve_min_P_Sts Cj_in_wP any_Ck_in_wP Suc.prems by force then have "(C, j) \# lnth (lmap wP_of_wstate Sts) (Suc (t_C + t_Cj + t))" using Suc.prems by auto then show ?case by (smt Suc.prems add.commute add_Suc_right lnth_lmap) qed then have "(\t. t_C + t_Cj \ t \ t < llength (lmap (set_mset \ wP_of_wstate) Sts) \ (C, j) \# wP_of_wstate (lnth Sts t))" using Ci_stays[of "_ - (t_C + t_Cj)"] by (metis le_add_diff_inverse llength_lmap) then have "(C, j) \ Liminf_llist (lmap (set_mset \ wP_of_wstate) Sts)" unfolding Liminf_llist_def using j_p by auto then show "\i. (C, i) \ Liminf_llist (lmap (set_mset \ wP_of_wstate) Sts)" by auto qed lemma lfinite_not_LNil_nth_llast: assumes "lfinite Sts" and "Sts \ LNil" shows "\i < llength Sts. lnth Sts i = llast Sts \ (\j < llength Sts. j \ i)" using assms proof (induction rule: lfinite.induct) case (lfinite_LConsI xs x) then show ?case proof (cases "xs = LNil") case True show ?thesis using True zero_enat_def by auto next case False then obtain i where i_p: "enat i < llength xs \ lnth xs i = llast xs \ (\j < llength xs. j \ enat i)" using lfinite_LConsI by auto then have "enat (Suc i) < llength (LCons x xs)" by (simp add: Suc_ile_eq) moreover from i_p have "lnth (LCons x xs) (Suc i) = llast (LCons x xs)" by (metis gr_implies_not_zero llast_LCons llength_lnull lnth_Suc_LCons) moreover from i_p have "\j < llength (LCons x xs). j \ enat (Suc i)" by (metis antisym_conv2 eSuc_enat eSuc_ile_mono ileI1 iless_Suc_eq llength_LCons) ultimately show ?thesis by auto qed qed auto lemma fair_if_finite: assumes fin: "lfinite Sts" shows "fair_state_seq (lmap state_of_wstate Sts)" proof (rule ccontr) assume unfair: "\ fair_state_seq (lmap state_of_wstate Sts)" have no_inf_from_last: "\y. \ llast Sts \\<^sub>w y" using fin full_chain_iff_chain[of "(\\<^sub>w)" Sts] full_deriv by auto from unfair obtain C where "C \ Liminf_llist (lmap N_of_state (lmap state_of_wstate Sts)) \ Liminf_llist (lmap P_of_state (lmap state_of_wstate Sts))" unfolding fair_state_seq_def Liminf_state_def by auto then obtain i where i_p: "enat i < llength Sts" "\j. i \ j \ enat j < llength Sts \ C \ N_of_state (state_of_wstate (lnth Sts j)) \ P_of_state (state_of_wstate (lnth Sts j))" unfolding Liminf_llist_def by auto have C_in_llast: "C \ N_of_state (state_of_wstate (llast Sts)) \ P_of_state (state_of_wstate (llast Sts))" proof - obtain l where l_p: "enat l < llength Sts \ lnth Sts l = llast Sts \ (\j < llength Sts. j \ enat l)" using fin lfinite_not_LNil_nth_llast i_p(1) by fastforce then have "C \ N_of_state (state_of_wstate (lnth Sts l)) \ P_of_state (state_of_wstate (lnth Sts l))" using i_p(1) i_p(2)[of l] by auto then show ?thesis using l_p by auto qed define N :: "'a wclause multiset" where "N = wN_of_wstate (llast Sts)" define P :: "'a wclause multiset" where "P = wP_of_wstate (llast Sts)" define Q :: "'a wclause multiset" where "Q = wQ_of_wstate (llast Sts)" define n :: nat where "n = n_of_wstate (llast Sts)" { assume "N_of_state (state_of_wstate (llast Sts)) \ {}" then obtain D j where "(D, j) \# N" unfolding N_def by (cases "llast Sts") auto then have "llast Sts \\<^sub>w (N - {#(D, j)#}, P + {#(D, j)#}, Q, n)" using weighted_RP.clause_processing[of "N - {#(D, j)#}" D j P Q n] unfolding N_def P_def Q_def n_def by auto then have "\St'. llast Sts \\<^sub>w St'" by auto } moreover { assume a: "N_of_state (state_of_wstate (llast Sts)) = {}" then have b: "N = {#}" unfolding N_def by (cases "llast Sts") auto from a have "C \ P_of_state (state_of_wstate (llast Sts))" using C_in_llast by auto then obtain D j where "(D, j) \# P" unfolding P_def by (cases "llast Sts") auto then have "weight (D, j) \ weight ` set_mset P" by auto then have "\w. is_least (\w. w \ (weight ` set_mset P)) w" using least_exists by auto then have "\D j. (\(D', j') \# P. weight (D, j) \ weight (D', j')) \ (D, j) \# P" using assms linorder_not_less unfolding is_least_def by (auto 6 0) then obtain D j where min: "(\(D', j') \# P. weight (D, j) \ weight (D', j'))" and Dj_in_p: "(D, j) \# P" by auto from min have min: "(\(D', j') \# P - {#(D, j)#}. weight (D, j) \ weight (D', j'))" using mset_subset_diff_self[OF Dj_in_p] by auto define N' where "N' = mset_set ((\D'. (D', n)) ` concls_of (inference_system.inferences_between (ord_FO_\ S) (set_mset (image_mset fst Q)) D))" have "llast Sts \\<^sub>w (N', {#(D', j') \# P - {#(D, j)#}. D' \ D#}, Q + {#(D,j)#}, Suc n)" using weighted_RP.inference_computation[of "P - {#(D, j)#}" D j N' n Q, OF min N'_def] of_wstate_split[symmetric, of "llast Sts"] Dj_in_p unfolding N_def[symmetric] P_def[symmetric] Q_def[symmetric] n_def[symmetric] b by auto then have "\St'. llast Sts \\<^sub>w St'" by auto } ultimately have "\St'. llast Sts \\<^sub>w St'" by auto then show False using no_inf_from_last by metis qed lemma N_of_state_state_of_wstate_wN_of_wstate: assumes "C \ N_of_state (state_of_wstate St)" shows "\i. (C, i) \# wN_of_wstate St" by (smt N_of_state.elims assms eq_fst_iff fstI fst_conv image_iff of_wstate_split set_image_mset state_of_wstate.simps) lemma in_wN_of_wstate_in_N_of_wstate: "(C, i) \# wN_of_wstate St \ C \ N_of_wstate St" by (metis (mono_guards_query_query) N_of_state.simps fst_conv image_eqI of_wstate_split set_image_mset state_of_wstate.simps) lemma in_wP_of_wstate_in_P_of_wstate: "(C, i) \# wP_of_wstate St \ C \ P_of_wstate St" by (metis (mono_guards_query_query) P_of_state.simps fst_conv image_eqI of_wstate_split set_image_mset state_of_wstate.simps) lemma in_wQ_of_wstate_in_Q_of_wstate: "(C, i) \# wQ_of_wstate St \ C \ Q_of_wstate St" by (metis (mono_guards_query_query) Q_of_state.simps fst_conv image_eqI of_wstate_split set_image_mset state_of_wstate.simps) lemma n_of_wstate_weighted_RP_increasing: "St \\<^sub>w St' \ n_of_wstate St \ n_of_wstate St'" by (induction rule: weighted_RP.induct) auto lemma nth_of_wstate_monotonic: assumes "j < llength Sts" and "i \ j" shows "n_of_wstate (lnth Sts i) \ n_of_wstate (lnth Sts j)" using assms proof (induction "j - i" arbitrary: i) case (Suc x) then have "x = j - (i + 1)" by auto then have "n_of_wstate (lnth Sts (i + 1)) \ n_of_wstate (lnth Sts j)" using Suc by auto moreover have "i < j" using Suc by auto then have "Suc i < llength Sts" using Suc by (metis enat_ord_simps(2) le_less_Suc_eq less_le_trans not_le) then have "lnth Sts i \\<^sub>w lnth Sts (Suc i)" using deriv chain_lnth_rel[of "(\\<^sub>w)" Sts i] by auto then have "n_of_wstate (lnth Sts i) \ n_of_wstate (lnth Sts (i + 1))" using n_of_wstate_weighted_RP_increasing[of "lnth Sts i" "lnth Sts (i + 1)"] by auto ultimately show ?case by auto qed auto lemma infinite_chain_relation_measure: assumes measure_decreasing: "\St St'. P St \ R St St' \ (m St', m St) \ mR" and non_infer_chain: "chain R (ldrop (enat k) Sts)" and inf: "llength Sts = \" and P: "\i. P (lnth (ldrop (enat k) Sts) i)" shows "chain (\x y. (x, y) \ mR)\\ (lmap m (ldrop (enat k) Sts))" proof (rule lnth_rel_chain) show "\ lnull (lmap m (ldrop (enat k) Sts))" using assms by auto next from inf have ldrop_inf: "llength (ldrop (enat k) Sts) = \ \ \ lfinite (ldrop (enat k) Sts)" using inf by (auto simp: llength_eq_infty_conv_lfinite) { fix j :: "nat" define St where "St = lnth (ldrop (enat k) Sts) j" define St' where "St' = lnth (ldrop (enat k) Sts) (j + 1)" have P': "P St \ P St'" unfolding St_def St'_def using P by auto from ldrop_inf have "R St St'" unfolding St_def St'_def using non_infer_chain infinite_chain_lnth_rel[of "ldrop (enat k) Sts" R j] by auto then have "(m St', m St) \ mR" using measure_decreasing P' by auto then have "(lnth (lmap m (ldrop (enat k) Sts)) (j + 1), lnth (lmap m (ldrop (enat k) Sts)) j) \ mR" unfolding St_def St'_def using lnth_lmap by (smt enat.distinct(1) enat_add_left_cancel enat_ord_simps(4) inf ldrop_lmap llength_lmap lnth_ldrop plus_enat_simps(3)) } then show "\j. enat (j + 1) < llength (lmap m (ldrop (enat k) Sts)) \ (\x y. (x, y) \ mR)\\ (lnth (lmap m (ldrop (enat k) Sts)) j) (lnth (lmap m (ldrop (enat k) Sts)) (j + 1))" by blast qed theorem weighted_RP_fair: "fair_state_seq (lmap state_of_wstate Sts)" proof (rule ccontr) assume asm: "\ fair_state_seq (lmap state_of_wstate Sts)" then have inff: "\ lfinite Sts" using fair_if_finite by auto then have inf: "llength Sts = \" using llength_eq_infty_conv_lfinite by auto from asm obtain C where "C \ Liminf_llist (lmap N_of_state (lmap state_of_wstate Sts)) \ Liminf_llist (lmap P_of_state (lmap state_of_wstate Sts))" unfolding fair_state_seq_def Liminf_state_def by auto then show False proof assume "C \ Liminf_llist (lmap N_of_state (lmap state_of_wstate Sts))" then obtain x where "enat x < llength Sts" "\xa. x \ xa \ enat xa < llength Sts \ C \ N_of_state (state_of_wstate (lnth Sts xa))" unfolding Liminf_llist_def by auto then have "\k. \j. k \ j \ (\i. (C, i) \# wN_of_wstate (lnth Sts j))" unfolding Liminf_llist_def by (force simp add: inf N_of_state_state_of_wstate_wN_of_wstate) then obtain k where k_p: "\j. k \ j \ \i. (C, i) \# wN_of_wstate (lnth Sts j)" unfolding Liminf_llist_def by auto have chain_drop_Sts: "chain (\\<^sub>w) (ldrop k Sts)" using deriv inf inff by (simp add: inf_chain_ldropn_chain ldrop_enat) have in_N_j: "\j. \i. (C, i) \# wN_of_wstate (lnth (ldrop k Sts) j)" using k_p by (simp add: add.commute inf) then have "chain (\x y. (x, y) \ RP_filtered_relation)\\ (lmap (RP_filtered_measure (\Ci. True)) (ldrop k Sts))" using inff inf weighted_RP_measure_decreasing_N chain_drop_Sts infinite_chain_relation_measure[of "\St. \i. (C, i) \# wN_of_wstate St" "(\\<^sub>w)"] by blast then show False using wfP_iff_no_infinite_down_chain_llist[of "\x y. (x, y) \ RP_filtered_relation"] wf_RP_filtered_relation inff by (metis (no_types, lifting) inf_llist_lnth ldrop_enat_inf_llist lfinite_inf_llist lfinite_lmap wfPUNIVI wf_induct_rule) next assume asm: "C \ Liminf_llist (lmap P_of_state (lmap state_of_wstate Sts))" from asm obtain i where i_p: "enat i < llength Sts" "\j. i \ j \ enat j < llength Sts \ C \ P_of_state (state_of_wstate (lnth Sts j))" unfolding Liminf_llist_def by auto then obtain i where "(C, i) \ Liminf_llist (lmap (set_mset \ wP_of_wstate) Sts)" using persistent_wclause_in_P_if_persistent_clause_in_P[of C] using asm inf by auto then have "\l. \k \ l. (C, i) \ (set_mset \ wP_of_wstate) (lnth Sts k)" unfolding Liminf_llist_def using inff inf by auto then obtain k where k_p: "(\k'\k. (C, i) \ (set_mset \ wP_of_wstate) (lnth Sts k'))" by blast have Ci_in: "\k'. (C, i) \ (set_mset \ wP_of_wstate) (lnth (ldrop k Sts) k')" using k_p lnth_ldrop[of k _ Sts] inf inff by force then have Ci_inn: "\k'. (C, i) \# (wP_of_wstate) (lnth (ldrop k Sts) k')" by auto have "chain (\\<^sub>w) (ldrop k Sts)" using deriv inf_chain_ldropn_chain inf inff by (simp add: inf_chain_ldropn_chain ldrop_enat) then have "chain (\x y. (x, y) \ RP_combined_relation)\\ (lmap (RP_combined_measure (weight (C, i))) (ldrop k Sts))" using inff inf Ci_in weighted_RP_measure_decreasing_P infinite_chain_relation_measure[of "\St. (C, i) \# wP_of_wstate St" "(\\<^sub>w)" "RP_combined_measure (weight (C, i))" ] by auto then show False using wfP_iff_no_infinite_down_chain_llist[of "\x y. (x, y) \ RP_combined_relation"] wf_RP_combined_relation inff by (smt inf_llist_lnth ldrop_enat_inf_llist lfinite_inf_llist lfinite_lmap wfPUNIVI wf_induct_rule) qed qed corollary weighted_RP_saturated: "src.saturated_upto (Liminf_llist (lmap grounding_of_wstate Sts))" using RP_saturated_if_fair[OF deriv_RP weighted_RP_fair empty_Q0_RP, unfolded llist.map_comp] by simp corollary weighted_RP_complete: "\ satisfiable (grounding_of_wstate (lhd Sts)) \ {#} \ Q_of_state (Liminf_wstate Sts)" using RP_complete_if_fair[OF deriv_RP weighted_RP_fair empty_Q0_RP, simplified lhd_lmap_Sts] . end end locale weighted_FO_resolution_prover_with_size_timestamp_factors = FO_resolution_prover S subst_atm id_subst comp_subst renamings_apart atm_of_atms mgu less_atm 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 literal multiset list \ 's list" and atm_of_atms :: "'a list \ 'a" and mgu :: "'a set set \ 's option" and less_atm :: "'a \ 'a \ bool" + fixes size_atm :: "'a \ nat" and size_factor :: nat and timestamp_factor :: nat assumes timestamp_factor_pos: "timestamp_factor > 0" begin fun weight :: "'a wclause \ nat" where "weight (C, i) = size_factor * size_multiset (size_literal size_atm) C + timestamp_factor * i" lemma weight_mono: "i < j \ weight (C, i) < weight (C, j)" using timestamp_factor_pos by simp declare weight.simps [simp del] sublocale wrp: weighted_FO_resolution_prover _ _ _ _ _ _ _ _ weight by unfold_locales (rule weight_mono) notation wrp.weighted_RP (infix "\\<^sub>w" 50) 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,1541 +1,1548 @@ (* 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" 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" - assumes deriv: "chain (\) Sts" begin -lemmas lhd_lmap_Sts = llist.map_sel(1)[OF chain_not_lnull[OF deriv]] - 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" 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 \ \)" 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) \ {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) 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" 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 sr_ext.derive (lmap grounding_of_state Sts)" - using deriv RP_ground_derive by (simp add: chain_lmap[of "(\)"]) +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 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 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 c d unfolding ns by blast + 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 ns c d by blast + 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 ns c d by blast + 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 from v have "\\'. D' \ \' = C" using \ variants_imp_exists_subtitution 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) 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 ns c] D_p i_p by blast + 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 fair ns c _ D'_p(3) D'_p(6) D'_p(5)] by blast + 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 fair ns c _ l'_p(2)] D'_p by auto + 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 fair ns c a i_p(1) D_p(2) D_p(3)] by auto + 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 fair ns c l'_p(1) l'_p(2)] D_p(3) \(1) \(2) D_p(2) by auto + 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 fair ns c a i_p(1)] \ D_p(2,3) by auto + 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))" + 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) fair ns C_p ground_C by auto + 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 - empty_in: "{#} \ Liminf_llist (lmap grounding_of_state Sts)" and - fair: "fair_state_seq Sts" + 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 fair ns] by auto + 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 apply - apply (erule disjE) subgoal apply (rule disjI1) using D_\_p by auto subgoal apply (erule HOL.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 "{#} \ clss_of_state (Liminf_state Sts)" + 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 by blast + using sr_ext.sat_limit_iff ground_derive_chain deriv by blast then show ?thesis - unfolding lhd_lmap_Sts . + 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) C'_p(5) j_p'(2) in force) + 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))" - unfolding sr_ext.sat_limit_iff[OF ground_derive_chain] - by (rule unsat[folded lhd_lmap_Sts[of grounding_of_state]]) + 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 fair empty_Q0, simplified]) + 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 fair by auto + using empty_clause_in_Q_of_Liminf_state[OF deriv fair] by auto qed end end end