theory Util imports
Main "HOL-Library.Sublist" "HOL-Library.Multiset"
begin
abbreviation swap_events where "swap_events i j t ≡ take i t @ [t ! j, t ! i] @ take (j - (i+1)) (drop (i+1) t) @ drop (j+1) t"
lemma swap_neighbors_2: shows "i+1 < length t ==> swap_events i (i+1) t = (t[i := t ! (i+1)])[i+1 := t ! i]" proof (induct i arbitrary: t) case0 thenshow ?case by (metis One_nat_def Suc_eq_plus1 add_lessD1 append.left_neutral append_Cons cancel_comm_monoid_add_class.diff_cancel drop_update_cancel length_list_update numeral_One take_0 take_Cons_numeral upd_conv_take_nth_drop zero_less_Suc) next case (Suc n) let ?t = "tl t" have"t = hd t # ?t" by (metis Suc.prems hd_Cons_tl list.size(3) not_less_zero) moreoverhave"swap_events n (n+1) ?t = (?t[n := ?t ! (n+1)])[n+1 := ?t ! n]" by (metis Suc.hyps Suc.prems Suc_eq_plus1 length_tl less_diff_conv) ultimatelyshow ?case by (metis Suc_eq_plus1 append_Cons diff_self_eq_0 drop_Suc_Cons list_update_code(3) nth_Cons_Suc take_Suc_Cons) qed
lemma swap_identical_length: assumes "i < j"and "j < length t" shows "length t = length (swap_events i j t)" proof - have"length (take i t @ [t ! j, t ! i] @ take (j - (i+1)) (drop (i+1) t)) = length (take i t) + length [t ! j, t ! i] + length (take (j - (i+1)) (drop (i+1) t))" by simp thenhave"... = j+1" using assms(1) assms(2) by auto thenshow ?thesis using assms(2) by auto qed
lemma swap_identical_heads: assumes "i < j"and "j < length t" shows "take i t = take i (swap_events i j t)" using assms by auto
lemma swap_identical_tails: assumes "i < j"and "j < length t" shows "drop (j+1) t = drop (j+1) (swap_events i j t)" proof - have"length (take i t @ [t ! j, t ! i] @ take (j - (i+1)) (drop (i+1) t)) = length (take i t) + length [t ! j, t ! i] + length (take (j - (i+1)) (drop (i+1) t))" by simp thenhave"... = j+1" using assms(1) assms(2) by auto thenshow ?thesis by (metis ‹length (take i t @ [t ! j, t ! i] @ take (j - (i + 1)) (drop (i + 1) t)) = length (take i t) + length [t ! j, t ! i] + length (take (j - (i + 1)) (drop (i + 1) t))› append.assoc append_eq_conv_conj) qed
lemma swap_neighbors: shows "i+1 < length l ==> (l[i := l ! (i+1)])[i+1 := l ! i] = take i l @ [l ! (i+1), l ! i] @ drop (i+2) l" proof (induct i arbitrary: l) case0 thenshow ?case by (metis One_nat_def add.left_neutral add_lessD1 append_Cons append_Nil drop_update_cancel length_list_update one_add_one plus_1_eq_Suc take0 take_Suc_Cons upd_conv_take_nth_drop zero_less_two) next case (Suc n) let ?l = "tl l" have"(l[Suc n := l ! (Suc n + 1)])[Suc n + 1 := l ! Suc n] = hd l # (?l[n := ?l ! (n+1)])[n+1 := ?l ! n]" by (metis Suc.prems add.commute add_less_same_cancel2 list.collapse list.size(3) list_update_code(3) not_add_less2 nth_Cons_Suc plus_1_eq_Suc) have"n + 1 < length ?l"using Suc.prems by auto thenhave"(?l[n := ?l ! (n+1)])[n+1 := ?l ! n] = take n ?l @ [?l ! (n+1), ?l ! n] @ drop (n+2) ?l" using Suc.hyps by simp thenshow ?case by (cases l) auto qed
lemma swap_events_perm: assumes "i < j"and "j < length t" shows "mset (swap_events i j t) = mset t" proof - have swap: "swap_events i j t = take i t @ [t ! j, t ! i] @ (take (j - (i+1)) (drop (i+1) t)) @ (drop (j+1) t)" by auto have reg: "t = take i t @ (take ((j+1) - i) (drop i t)) @ drop (j+1) t" by (metis add_diff_inverse_nat add_lessD1 append.assoc append_take_drop_id assms(1) less_imp_add_positive less_not_refl take_add) have"mset (take i t) = mset (take i t)"by simp moreoverhave"mset (drop (j+1) t) = mset (drop (j+1) t)"by simp moreoverhave"mset ([t ! j, t ! i] @ (take (j - (i+1)) (drop (i+1) t))) = mset (take ((j+1) - i) (drop i t))" proof - let ?l = "take (j - (i+1)) (drop (i+1) t)" have"take ((j+1) - i) (drop i t) = t ! i # ?l @ [t ! j]" proof - have f1: "Suc (j - Suc i) = j - i" by (meson Suc_diff_Suc assms(1)) have f2: "i < length t" using assms(1) assms(2) by linarith have f3: "j - (i + 1) + (i + 1) = j" using‹i < j›by simp thenhave"drop (j - (i + 1)) (drop (i + 1) t) = drop j t" by (metis drop_drop) thenshow ?thesis using f3 f2 f1 by (metis (no_types) Cons_nth_drop_Suc Suc_diff_le Suc_eq_plus1 assms(1) assms(2) hd_drop_conv_nth length_drop less_diff_conv nat_less_le take_Suc_Cons take_hd_drop) qed thenshow ?thesis by fastforce qed ultimatelyshow ?thesis using swap reg by simp (metis mset_append union_mset_add_mset_left union_mset_add_mset_right) qed
lemma sum_eq_if_same_subterms: fixes
i :: nat shows "∀k. i ≤ k ∧ k < j ⟶ f k = f' k ==> sum f {i..<j} = sum f' {i..<j}" by auto
lemma filter_neq_takeWhile: assumes "filter ((≠) a) l ≠ takeWhile ((≠) a) l" shows "∃i j. i < j ∧ j < length l ∧ l ! i = a ∧ l ! j ≠ a" (is ?P) proof (rule ccontr) assume"~ ?P" thenhave asm: "∀i j. i < j ∧ j < length l ⟶ l ! i ≠ a ∨ l ! j = a" (is ?Q) by simp thenhave"filter ((≠) a) l = takeWhile ((≠) a) l" proof (cases "a : set l") case False thenhave"∀i. i < length l ⟶ l ! i ≠ a"by auto thenshow ?thesis by (metis (mono_tags, lifting) False filter_True takeWhile_eq_all_conv) next case True thenhave ex_j: "∃j. j < length l ∧ l ! j = a" by (simp add: in_set_conv_nth) let ?j = "Min {j. j < length l ∧ l ! j = a}" have fin_j: "finite {j. j < length l ∧ l ! j = a}" using finite_nat_set_iff_bounded by blast moreoverhave"{j. j < length l ∧ l ! j = a} ≠ empty"using ex_j by blast ultimatelyhave"?j < length l" using Min_less_iff by blast have tail_all_a: "∀j. j < length l ∧ j ≥ ?j ⟶ l ! j = a" proof (rule allI, rule impI) fix j assume"j < length l ∧ j ≥ ?j" moreoverhave"[ ?Q; j < length l ∧ j ≥ ?j ]==>∀k. k ≥ ?j ∧ k ≤ j ⟶ l ! j = a" proof (induct "j - ?j") case0 thenhave"j = ?j"using0by simp thenshow ?case using Min_in ‹{j. j < length l ∧ l ! j = a} ≠ {}› fin_j by blast next case (Suc n) thenhave"∀k. k ≥ ?j ∧ k < j ⟶ l ! j = a" by (metis (mono_tags, lifting) Min_in ‹{j. j < length l ∧ l ! j = a} ≠ {}› fin_j le_eq_less_or_eq mem_Collect_eq) thenshow ?case using Suc.hyps(2) by auto qed ultimatelyshow"l ! j = a"using asm by blast qed moreoverhave head_all_not_a: "∀i. i < ?j ⟶ l ! i ≠ a"using asm calculation by (metis (mono_tags, lifting) Min_le ‹Min {j. j < length l ∧ l ! j = a} < length l› fin_j leD less_trans mem_Collect_eq) ultimatelyhave"takeWhile ((≠) a) l = take ?j l" proof - have"length (takeWhile ((≠) a) l) = ?j" proof - have"length (takeWhile ((≠) a) l) ≤ ?j" (is ?S) proof (rule ccontr) assume"¬ ?S" thenhave"l ! ?j ≠ a" by (metis (mono_tags, lifting) not_le_imp_less nth_mem set_takeWhileD takeWhile_nth) thenshow False using‹Min {j. j < length l ∧ l ! j = a} < length l› tail_all_a by blast qed moreoverhave"length (takeWhile ((≠) a) l) ≥ ?j" (is ?T) proof (rule ccontr) assume"¬ ?T" thenhave"∃j. j < ?j ∧ l ! j = a" by (metis (mono_tags, lifting) ‹Min {j. j < length l ∧ l ! j = a} < length l› calculation le_less_trans not_le_imp_less nth_length_takeWhile) thenshow False using head_all_not_a by blast qed ultimatelyshow ?thesis by simp qed moreoverhave"length (take ?j l) = ?j" by (metis calculation takeWhile_eq_take) ultimatelyshow ?thesis by (metis takeWhile_eq_take)
qed moreoverhave"filter ((≠) a) l = take ?j l" proof - have"filter ((≠) a) l = filter ((≠) a) (take ?j l) @ filter ((≠) a) (drop ?j l)" by (metis append_take_drop_id filter_append) moreoverhave"filter ((≠) a) (take ?j l) = take ?j l"using head_all_not_a by (metis ‹takeWhile ((≠) a) l = take (Min {j. j < length l ∧ l ! j = a}) l› filter_id_conv set_takeWhileD) moreoverhave"filter ((≠) a) (drop ?j l) = []" proof - have"∀j. j ≥ ?j ∧ j < length l ⟶ l ! j = drop ?j l ! (j - ?j)" by simp thenhave"∀j. j < length l - ?j ⟶ drop ?j l ! j = a"using tail_all_a by (metis (no_types, lifting) Groups.add_ac(2) ‹Min {j. j < length l ∧ l ! j = a} < length l› less_diff_conv less_imp_le_nat not_add_less2 not_le nth_drop) thenshow ?thesis proof - obtain aa :: "('a ==> bool) ==> 'a list ==> 'a"where "∀x0 x1. (∃v2. v2 ∈ set x1 ∧ x0 v2) = (aa x0 x1 ∈ set x1 ∧ x0 (aa x0 x1))" by moura thenhave f1: "∀as p. aa p as ∈ set as ∧ p (aa p as) ∨ filter p as = []" by (metis (full_types) filter_False) obtain nn :: "'a list ==> 'a ==> nat"where
f2: "∀x0 x1. (∃v2<length x0. x0 ! v2 = x1) = (nn x0 x1 < length x0 ∧ x0 ! nn x0 x1 = x1)" by moura
{ assume"drop (Min {n. n < length l ∧ l ! n = a}) l ! nn (drop (Min {n. n < length l ∧ l ! n = a}) l) (aa ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l)) = a" thenhave"filter ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l) = [] ∨¬ nn (drop (Min {n. n < length l ∧ l ! n = a}) l) (aa ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l)) < length (drop (Min {n. n < length l ∧ l ! n = a}) l) ∨ drop (Min {n. n < length l ∧ l ! n = a}) l ! nn (drop (Min {n. n < length l ∧ l ! n = a}) l) (aa ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l)) ≠ aa ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l)" using f1 by (metis (full_types)) } moreover
{ assume"¬ nn (drop (Min {n. n < length l ∧ l ! n = a}) l) (aa ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l)) < length l - Min {n. n < length l ∧ l ! n = a}" thenhave"¬ nn (drop (Min {n. n < length l ∧ l ! n = a}) l) (aa ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l)) < length (drop (Min {n. n < length l ∧ l ! n = a}) l) ∨ drop (Min {n. n < length l ∧ l ! n = a}) l ! nn (drop (Min {n. n < length l∧ l ! n = a}) l) (aa ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l)) ≠ aa ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l)" by simp } ultimatelyhave"filter ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l) = [] ∨¬ nn (drop (Min {n. n < length l ∧ l ! n = a}) l) (aa ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l)) < length (drop (Min {n. n < length l ∧ l ! n = a}) l) ∨ drop (Min {n. n < length l ∧ l ! n = a}) l ! nn (drop (Min {n. n < length l ∧ l ! n = a}) l) (aa ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l)) ≠ aa ((≠) a) (drop (Min {n. n < length l ∧ l ! n = a}) l)" using‹∀j<length l - Min {j. j < length l ∧ l ! j = a}. drop (Min {j. j < length l ∧ l ! j = a}) l ! j = a›by blast thenshow ?thesis using f2 f1 by (meson in_set_conv_nth) qed qed ultimatelyshow ?thesis by simp qed ultimatelyshow ?thesis by simp qed thenshow False using assms by simp qed
lemma util_exactly_one_element: assumes "m ∉ set l"and "l' = l @ [m]" shows "∃!j. j < length l' ∧ l' ! j = m" (is ?P) proof - have"∀j. j < length l' - 1 ⟶ l' ! j ≠ m" by (metis assms(1) assms(2) butlast_snoc length_butlast nth_append nth_mem) thenhave one_j: "∀j. j < length l' ∧ l' ! j = m ⟶ j = (length l' - 1)" by (metis (no_types, opaque_lifting) diff_Suc_1 lessE) show ?thesis proof (rule ccontr) assume"~ ?P" thenobtain i j where"i ≠ j""i < length l'""j < length l'" "l' ! i = m""l' ! j = m" using assms by auto thenshow False using one_j by blast qed qed
lemma exists_one_iff_filter_one: shows "(∃!j. j < length l ∧ l ! j = a) ⟷ length (filter ((=) a) l) = 1" proof (rule iffI) assume"∃!j. j < length l ∧ l ! j = a" thenobtain j where"j < length l""l ! j = a" by blast moreoverhave"∀k. k ≠ j ∧ k < length l ⟶ l ! k ≠ a" using‹∃!j. j < length l ∧ l ! j = a›‹j < length l›‹l ! j = a›by blast moreoverhave"l = take j l @ [l ! j] @ drop (j+1) l" by (metis Cons_eq_appendI Cons_nth_drop_Suc Suc_eq_plus1 append_self_conv2 append_take_drop_id calculation(1) calculation(2)) moreoverhave"filter ((=) a) (take j l) = []" proof - have"∀k. k < length (take j l) ⟶ (take j l) ! k ≠ a" using calculation(3) by auto thenshow ?thesis by (metis (full_types) filter_False in_set_conv_nth) qed moreoverhave"filter ((=) a) (drop (j+1) l) = []" proof - have"∀k. k < length (drop (j+1) l) ⟶ (drop (j+1) l) ! k ≠ a" using calculation(3) by auto thenshow ?thesis by (metis (full_types) filter_False in_set_conv_nth) qed ultimatelyshow"length (filter ((=) a) l) = 1" by (metis (mono_tags, lifting) One_nat_def Suc_eq_plus1 append_Cons append_self_conv2 filter.simps(2) filter_append list.size(3) list.size(4)) next assume asm: "length (filter ((=) a) l) = 1" thenhave"filter ((=) a) l = [a]" proof - let ?xs = "filter ((=) a) l" have"length ?xs = 1" using asm by blast thenshow ?thesis by (metis (full_types) Cons_eq_filterD One_nat_def length_0_conv length_Suc_conv) qed thenhave"∃j. j < length l ∧ l ! j = a" by (metis (full_types) filter_False in_set_conv_nth list.discI) thenobtain j where j: "j < length l""l ! j = a"by blast moreoverhave"∀k. k < length l ∧ k ≠ j ⟶ l ! k ≠ a" proof (rule allI, rule impI) fix k assume assm: "k < length l ∧ k ≠ j" thenhave‹k < length l› .. show"l ! k ≠ a" proof (rule ccontr) assume lka: "¬ l ! k ≠ a" thenhave‹l ! k = a› by simp show False proof (cases "k < j") let ?xs = "take (k+1) l" let ?ys = "drop (k+1) l" case True thenhave"length (filter ((=) a) ?xs) > 0" using‹k < length l›‹l ! k = a›by (auto simp add: filter_empty_conv in_set_conv_nth) moreoverhave"length (filter ((=) a) ?ys) > 0" proof - have"?ys ! (j - (k+1)) = l ! j" using True assm by auto moreoverhave"j - (k+1) < length ?ys" using True ‹j < length l›by auto ultimatelyshow ?thesis by (metis (full_types) ‹l ! j = a› filter_empty_conv length_greater_0_conv nth_mem) qed moreoverhave"?xs @ ?ys = l" using append_take_drop_id by blast ultimatelyhave"length (filter ((=) a) l) > 1" by (metis (no_types, lifting) One_nat_def Suc_eq_plus1 asm filter_append length_append less_add_eq_less less_one nat_neq_iff) thenshow False using asm by simp next let ?xs = "take (j+1) l" let ?ys = "drop (j+1) l" case False thenhave"length (filter ((=) a) ?xs) > 0" using‹k < length l›‹l ! j = a›by (auto simp add: filter_empty_conv in_set_conv_nth) moreoverhave"length (filter ((=) a) ?ys) > 0" proof - have"?ys ! (k - (j+1)) = l ! k" using False assm by auto moreoverhave"k - (j+1) < length ?ys" using False assm by auto ultimatelyshow ?thesis by (metis (full_types) filter_empty_conv length_greater_0_conv lka nth_mem) qed moreoverhave"?xs @ ?ys = l" using append_take_drop_id by blast ultimatelyhave"length (filter ((=) a) l) > 1" by (metis (no_types, lifting) One_nat_def Suc_eq_plus1 asm filter_append length_append less_add_eq_less less_one nat_neq_iff) thenshow False using asm by simp qed qed qed ultimatelyshow"∃!j. j < length l ∧ l ! j = a"by blast qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.