theory CDCL_W_Level imports Entailment_Definition.Partial_Annotated_Herbrand_Interpretation begin subsubsection ‹Level of literals and clauses› text ‹Getting the level of a variable, implies that the list has to be reversed. Here is the function ∗‹after› reversing.› definition count_decided :: "('v, 'b, 'm) annotated_lit list ⇒ nat" where "count_decided l = length (filter is_decided l)" definition get_level :: "('v, 'm) ann_lits ⇒ 'v literal ⇒ nat" where "get_level S L = length (filter is_decided (dropWhile (λS. atm_of (lit_of S) ≠ atm_of L) S))" lemma get_level_uminus[simp]: ‹get_level M (-L) = get_level M L› by (auto simp: get_level_def) lemma get_level_Neg_Pos: ‹get_level M (Neg L) = get_level M (Pos L)› unfolding get_level_def by auto lemma count_decided_0_iff: ‹count_decided M = 0 ⟷ (∀L ∈ set M. ¬is_decided L)› by (auto simp: count_decided_def filter_empty_conv) lemma shows count_decided_nil[simp]: ‹count_decided [] = 0› and count_decided_cons[simp]: ‹count_decided (a # M) = (if is_decided a then Suc (count_decided M) else count_decided M)› and count_decided_append[simp]: ‹count_decided (M @ M') = count_decided M + count_decided M'› by (auto simp: count_decided_def) lemma atm_of_notin_get_level_eq_0[simp]: assumes "undefined_lit M L" shows "get_level M L = 0" using assms by (induct M rule: ann_lit_list_induct) (auto simp: get_level_def defined_lit_map) lemma get_level_ge_0_atm_of_in: assumes "get_level M L > n" shows "atm_of L ∈ atm_of ` lits_of_l M" using atm_of_notin_get_level_eq_0[of M L] assms unfolding defined_lit_map by (auto simp: lits_of_def simp del: atm_of_notin_get_level_eq_0) text ‹In @{const get_level} (resp. @{const get_level}), the beginning (resp. the end) can be skipped if the literal is not in the beginning (resp. the end).› lemma get_level_skip[simp]: assumes "undefined_lit M L" shows "get_level (M @ M') L = get_level M' L" using assms by (induct M rule: ann_lit_list_induct) (auto simp: get_level_def defined_lit_map) text ‹If the literal is at the beginning, then the end can be skipped› lemma get_level_skip_end[simp]: assumes "defined_lit M L" shows "get_level (M @ M') L = get_level M L + count_decided M'" using assms by (induct M' rule: ann_lit_list_induct) (auto simp: lits_of_def get_level_def count_decided_def defined_lit_map) lemma get_level_skip_beginning[simp]: assumes "atm_of L' ≠ atm_of (lit_of K)" shows "get_level (K # M) L' = get_level M L'" using assms by (auto simp: get_level_def) lemma get_level_take_beginning[simp]: assumes "atm_of L' = atm_of (lit_of K)" shows "get_level (K # M) L' = count_decided (K # M)" using assms by (auto simp: get_level_def count_decided_def) lemma get_level_cons_if: ‹get_level (K # M) L' = (if atm_of L' = atm_of (lit_of K) then count_decided (K # M) else get_level M L')› by auto lemma get_level_skip_beginning_not_decided[simp]: assumes "undefined_lit S L" and "∀s∈set S. ¬is_decided s" shows "get_level (M @ S) L = get_level M L" using assms apply (induction S rule: ann_lit_list_induct) apply auto[2] apply (case_tac "atm_of L ∈ atm_of ` lits_of_l M") apply (auto simp: image_iff lits_of_def filter_empty_conv count_decided_def defined_lit_map dest: set_dropWhileD) done lemma get_level_skip_all_not_decided[simp]: fixes M assumes "∀m∈set M. ¬ is_decided m" shows "get_level M L = 0" using assms by (auto simp: filter_empty_conv get_level_def dest: set_dropWhileD) text ‹the @{term "{#0#}"} is there to ensures that the set is not empty.› definition get_maximum_level :: "('a, 'b) ann_lits ⇒ 'a clause ⇒ nat" where "get_maximum_level M D = Max_mset ({#0#} + image_mset (get_level M) D)" lemma get_maximum_level_ge_get_level: "L ∈# D ⟹ get_maximum_level M D ≥ get_level M L" unfolding get_maximum_level_def by auto lemma get_maximum_level_empty[simp]: "get_maximum_level M {#} = 0" unfolding get_maximum_level_def by auto lemma get_maximum_level_exists_lit_of_max_level: "D ≠ {#} ⟹ ∃L∈# D. get_level M L = get_maximum_level M D" unfolding get_maximum_level_def apply (induct D) apply simp by (rename_tac x D, case_tac "D = {#}") (auto simp add: max_def) lemma get_maximum_level_empty_list[simp]: "get_maximum_level [] D = 0" unfolding get_maximum_level_def by (simp add: image_constant_conv) lemma get_maximum_level_add_mset: "get_maximum_level M (add_mset L D) = max (get_level M L) (get_maximum_level M D)" unfolding get_maximum_level_def by simp lemma get_level_append_if: ‹get_level (M @ M') L = (if defined_lit M L then get_level M L + count_decided M' else get_level M' L)› by (auto) text ‹Do mot activate as [simp] rules. It breaks everything.› lemma get_maximum_level_single: ‹get_maximum_level M {#x#} = get_level M x› by (auto simp: get_maximum_level_add_mset) lemma get_maximum_level_plus: "get_maximum_level M (D + D') = max (get_maximum_level M D) (get_maximum_level M D')" by (induction D) (simp_all add: get_maximum_level_add_mset) lemma get_maximum_level_cong: assumes ‹∀L ∈# D. get_level M L = get_level M' L› shows ‹get_maximum_level M D = get_maximum_level M' D› using assms by (induction D) (auto simp: get_maximum_level_add_mset) lemma get_maximum_level_exists_lit: assumes n: "n > 0" and max: "get_maximum_level M D = n" shows "∃L ∈#D. get_level M L = n" proof - have f: "finite (insert 0 ((λL. get_level M L) ` set_mset D))" by auto then have "n ∈ ((λL. get_level M L) ` set_mset D)" using n max Max_in[OF f] unfolding get_maximum_level_def by simp then show "∃L ∈# D. get_level M L = n" by auto qed lemma get_maximum_level_skip_first[simp]: assumes "atm_of (lit_of K) ∉ atms_of D" shows "get_maximum_level (K # M) D = get_maximum_level M D" using assms unfolding get_maximum_level_def atms_of_def atm_of_in_atm_of_set_iff_in_set_or_uminus_in_set by (smt atm_of_in_atm_of_set_in_uminus get_level_skip_beginning image_iff lit_of.simps(2) multiset.map_cong0) lemma get_maximum_level_skip_beginning: assumes DH: "∀x ∈# D. undefined_lit c x" shows "get_maximum_level (c @ H) D = get_maximum_level H D" proof - have "(get_level (c @ H)) ` set_mset D = (get_level H) ` set_mset D" apply (rule image_cong) apply (simp; fail) using DH unfolding atms_of_def by auto then show ?thesis using DH unfolding get_maximum_level_def by auto qed lemma get_maximum_level_D_single_propagated: "get_maximum_level [Propagated x21 x22] D = 0" unfolding get_maximum_level_def by (simp add: image_constant_conv) lemma get_maximum_level_union_mset: "get_maximum_level M (A ∪# B) = get_maximum_level M (A + B)" unfolding get_maximum_level_def by (auto simp: image_Un) lemma count_decided_rev[simp]: "count_decided (rev M) = count_decided M" by (auto simp: count_decided_def rev_filter[symmetric]) lemma count_decided_ge_get_level: "count_decided M ≥ get_level M L" by (induct M rule: ann_lit_list_induct) (auto simp add: count_decided_def le_max_iff_disj get_level_def) lemma count_decided_ge_get_maximum_level: "count_decided M ≥ get_maximum_level M D" using get_maximum_level_exists_lit_of_max_level unfolding Bex_def by (metis get_maximum_level_empty count_decided_ge_get_level le0) lemma get_level_last_decided_ge: ‹defined_lit (c @ [Decided K]) L' ⟹ 0 < get_level (c @ [Decided K]) L'› by (induction c) (auto simp: defined_lit_cons get_level_cons_if) lemma get_maximum_level_mono: ‹D ⊆# D' ⟹ get_maximum_level M D ≤ get_maximum_level M D'› unfolding get_maximum_level_def by auto fun get_all_mark_of_propagated where "get_all_mark_of_propagated [] = []" | "get_all_mark_of_propagated (Decided _ # L) = get_all_mark_of_propagated L" | "get_all_mark_of_propagated (Propagated _ mark # L) = mark # get_all_mark_of_propagated L" lemma get_all_mark_of_propagated_append[simp]: "get_all_mark_of_propagated (A @ B) = get_all_mark_of_propagated A @ get_all_mark_of_propagated B" by (induct A rule: ann_lit_list_induct) auto lemma get_all_mark_of_propagated_tl_proped: ‹M ≠ [] ⟹ is_proped (hd M) ⟹ get_all_mark_of_propagated (tl M) = tl (get_all_mark_of_propagated M)› by (induction M rule: ann_lit_list_induct) auto subsubsection ‹Properties about the levels› lemma atm_lit_of_set_lits_of_l: "(λl. atm_of (lit_of l)) ` set xs = atm_of ` lits_of_l xs" unfolding lits_of_def by auto text ‹Before I try yet another time to prove that I can remove the assumption \<^term>‹no_dup M›: It does not work. The problem is that \<^term>‹get_level M K = Suc i› peaks the first occurrence of the literal \<^term>‹K›. This is for example an issue for the trail \<^term>‹replicate n (Decided K)›. An explicit counter-example is below. › lemma le_count_decided_decomp: assumes ‹no_dup M› shows ‹i < count_decided M ⟷ (∃c K c'. M = c @ Decided K # c' ∧ get_level M K = Suc i)› (is "?A ⟷ ?B") proof assume ?B then obtain c K c' where "M = c @ Decided K # c'" and "get_level M K = Suc i" by blast then show ?A using count_decided_ge_get_level[of M K] by auto next assume ?A then show ?B using ‹no_dup M› proof (induction M rule: ann_lit_list_induct) case Nil then show ?case by simp next case (Decided L M) note IH = this(1) and i = this(2) and n_d = this(3) then have n_d_M: "no_dup M" by simp show ?case proof (cases "i < count_decided M") case True then obtain c K c' where M: "M = c @ Decided K # c'" and lev_K: "get_level M K = Suc i" using IH n_d_M by blast show ?thesis apply (rule exI[of _ "Decided L # c"]) apply (rule exI[of _ K]) apply (rule exI[of _ c']) using lev_K n_d unfolding M by (auto simp: get_level_def defined_lit_map) next case False show ?thesis apply (rule exI[of _ "[]"]) apply (rule exI[of _ L]) apply (rule exI[of _ M]) using False i by (auto simp: get_level_def count_decided_def) qed next case (Propagated L mark' M) note i = this(2) and IH = this(1) and n_d = this(3) then obtain c K c' where M: "M = c @ Decided K # c'" and lev_K: "get_level M K = Suc i" by (auto simp: count_decided_def) show ?case apply (rule exI[of _ "Propagated L mark' # c"]) apply (rule exI[of _ "K"]) apply (rule exI[of _ "c'"]) using lev_K n_d unfolding M by (auto simp: atm_lit_of_set_lits_of_l get_level_def defined_lit_map) qed qed text ‹The counter-example if the assumption \<^term>‹no_dup M›.› lemma fixes K defines ‹M ≡ replicate 3 (Decided K)› defines ‹i ≡ 1› assumes ‹i < count_decided M ⟷ (∃c K c'. M = c @ Decided K # c' ∧ get_level M K = Suc i)› shows False using assms(3-) unfolding M_def i_def numeral_3_eq_3 by (auto simp: Cons_eq_append_conv) lemma Suc_count_decided_gt_get_level: ‹get_level M L < Suc (count_decided M)› by (induction M rule: ann_lit_list_induct) (auto simp: get_level_cons_if) lemma get_level_neq_Suc_count_decided[simp]: ‹get_level M L ≠ Suc (count_decided M)› using Suc_count_decided_gt_get_level[of M L] by auto lemma length_get_all_ann_decomposition: ‹length (get_all_ann_decomposition M) = 1+count_decided M› by (induction M rule: ann_lit_list_induct) auto lemma get_maximum_level_remove_non_max_lvl: ‹get_level M a < get_maximum_level M D ⟹ get_maximum_level M (remove1_mset a D) = get_maximum_level M D› by (cases ‹a ∈# D›) (auto dest!: multi_member_split simp: get_maximum_level_add_mset) lemma exists_lit_max_level_in_negate_ann_lits: ‹negate_ann_lits M ≠ {#} ⟹ ∃L∈#negate_ann_lits M. get_level M L = count_decided M› by (cases ‹M›) (auto simp: negate_ann_lits_def) end