(**************************************************************************************************) (**************************************************************************************************) section‹Basic Lemmas for Manipulating Indices and Lists› (**************************************************************************************************) (**************************************************************************************************)
fun flat_map :: "('a => 'b list) => 'a list => 'b list"where "flat_map f [] = []"
|"flat_map f (h#t) = (f h)@(flat_map f t)"
abbreviation(input) project_at_indices (‹π›) where "project_at_indices S as ≡ nths as S"
fun insert_at_index :: " 'a list ==>'a ==> nat ==> 'a list"where "insert_at_index as a n= (take n as) @ (a#(drop n as))"
lemma insert_at_index_length: shows"length (insert_at_index as a n) = length as + 1" by(induction n, auto)
lemma insert_at_index_eq[simp]: assumes"n ≤ length as" shows"(insert_at_index as a n)!n = a" by (metis assms insert_at_index.elims length_take min.absorb2 nth_append_length)
lemma insert_at_index_eq'[simp]: assumes"n ≤ length as" assumes"k < n" shows"(insert_at_index as a n)!k = as ! k" using assms by (simp add: nth_append)
lemma insert_at_index_eq''[simp]: assumes"n < length as" assumes"k ≤ n" shows"(insert_at_index as a k)!(Suc n) = as ! n" using assms insert_at_index.simps[of as a k] by (smt Suc_diff_Suc append_take_drop_id diff_Suc_Suc dual_order.order_iff_strict
le_imp_less_Suc length_take less_trans min.absorb2 not_le nth_Cons_Suc nth_append)
text‹Correctness of project\_at\_indices›
definition indices_of :: "'a list ==> nat set"where "indices_of as = {..<(length as)}"
lemma proj_at_index_list_length[simp]: assumes"S ⊆ indices_of as" shows"length (project_at_indices S as) = card S" proof- have"S = {i. i < length as ∧ i ∈ S}" using assms unfolding indices_of_def by blast thus ?thesis using length_nths[of as S] by auto qed
text‹A function which enumerates finite sets›
abbreviation(input) set_to_list :: "nat set ==> nat list"where "set_to_list S ≡ sorted_list_of_set S"
lemma set_to_list_empty: assumes"card S = 0" shows"set_to_list S = []" by (metis assms length_0_conv length_sorted_list_of_set)
lemma set_to_list_first: assumes"card S > 0" shows"Min S = set_to_list S ! 0 " proof- have0: "set (set_to_list S) = S" using assms card_ge_0_finite set_sorted_list_of_set by blast have1: "sorted (set_to_list S)" by simp show ?thesis apply(rule Min_eqI) using assms card_ge_0_finite apply blast apply (metis "0""1" in_set_conv_nth less_Suc0 less_or_eq_imp_le not_less_eq sorted_iff_nth_mono_less) by (metis "0" Max_in assms card_0_eq card_ge_0_finite gr_zeroI in_set_conv_nth not_less0) qed
lemma set_to_list_last: assumes"card S > 0" shows"Max S = last (set_to_list S)" proof- have0: "set (set_to_list S) = S" using assms card_ge_0_finite set_sorted_list_of_set by blast have1: "sorted (set_to_list S)" by simp show ?thesis apply(rule Max_eqI) using assms card_ge_0_finite apply blast apply (smt "0""1" Suc_diff_1 in_set_conv_nth last_conv_nth le_simps(2) length_greater_0_conv
less_or_eq_imp_le nat_neq_iff neq0_conv not_less_eq sorted_iff_nth_mono_less) by (metis "0" assms card.empty empty_set last_in_set less_numeral_extra(3)) qed
lemma set_to_list_insert_Max: assumes"finite S" assumes"∧s. s ∈ S ==> a > s" shows"set_to_list (insert a S) = set_to_list S @[a]" by (metis assms(1) assms(2) card_0_eq card_insert_if finite.insertI infinite_growing
insert_not_empty less_imp_le_nat sorted_insort_is_snoc sorted_list_of_set(1) sorted_list_of_set(2)
sorted_list_of_set_insert)
lemma set_to_list_insert_Min: assumes"finite S" assumes"∧s. s ∈ S ==> a < s" shows"set_to_list (insert a S) = a#set_to_list S" by (metis assms(1) assms(2) insort_is_Cons nat_less_le sorted_list_of_set(1) sorted_list_of_set_insert)
fun nth_elem where "nth_elem S n = set_to_list S ! n"
lemma nth_elem_closed: assumes"i < card S" shows"nth_elem S i ∈ S" by (metis assms card.infinite not_less0 nth_elem.elims nth_mem set_to_list_length sorted_list_of_set(1))
lemma nth_elem_Min: assumes"card S > 0" shows"nth_elem S 0 = Min S" by (simp add: assms set_to_list_first)
lemma nth_elem_Max: assumes"card S > 0" shows"nth_elem S (card S - 1) = Max S" proof- have"last (set_to_list S) = set_to_list S ! (card S - 1)" by (metis assms card_0_eq card_ge_0_finite last_conv_nth neq0_conv set_to_list_length sorted_list_of_set_eq_Nil_iff) thus ?thesis using assms set_to_list_last set_to_list_length by simp qed
lemma nth_elem_Suc: assumes"card S > Suc n" shows"nth_elem S (Suc n) > nth_elem S n" using assms sorted_sorted_list_of_set[of S] set_to_list_length[of S] by (metis Suc_lessD card.infinite distinct_sorted_list_of_set lessI nat_less_le not_less0 nth_elem.elims nth_eq_iff_index_eq sorted_iff_nth_mono_less)
lemma nth_elem_insert_Min: assumes"card S > 0" assumes"a < Min S" shows"nth_elem (insert a S) (Suc i) = nth_elem S i" using assms by (metis Min_gr_iff card_0_eq card_ge_0_finite neq0_conv nth_Cons_Suc nth_elem.elims set_to_list_insert_Min)
lemma set_to_list_Suc_map: assumes"finite S" shows"set_to_list (Suc ` S) = map Suc (set_to_list S)" proof- obtain n where n_def: "n = card S" by blast have"∧S. card S = n ==> set_to_list (Suc ` S) = map Suc (set_to_list S)" proof(induction n) case0 thenshow ?case by (metis card_eq_0_iff finite_imageD image_is_empty inj_Suc list.simps(8) set_to_list_empty) next case (Suc n) have0: "S = insert (Min S) (S - {Min S})" by (metis Min_in Suc.prems card_gt_0_iff insert_Diff zero_less_Suc) have1: "sorted_list_of_set (Suc ` (S - {Min S})) = map Suc (sorted_list_of_set (S - {Min S}))" by (metis "0" Suc.IH Suc.prems card_Diff_singleton card.infinite diff_Suc_1 insertI1 nat.simps(3)) have2: "set_to_list S = (Min S)#(set_to_list (S - {Min S}))" by (metis "0" DiffD1 Min_le Suc.prems card_Diff_singleton card.infinite card_insert_if
diff_Suc_1 finite_Diff n_not_Suc_n nat.simps(3) nat_less_le set_to_list_insert_Min) have3: "sorted_list_of_set (Suc ` S) = (Min (Suc ` S))#(set_to_list ((Suc ` S) - {Min (Suc ` S)}))" by (metis DiffD1 Diff_idemp Min_in Min_le Suc.prems card_Diff1_less card_eq_0_iff finite_Diff
finite_imageI image_is_empty insert_Diff nat.simps(3) nat_less_le set_to_list_insert_Min) have4: "(Min (Suc ` S)) = Suc (Min S)" by (metis Min.hom_commute Suc.prems Suc_le_mono card_eq_0_iff min_def nat.simps(3)) have5: "sorted_list_of_set (Suc ` S) = Suc (Min S)#(set_to_list ((Suc ` S) - {Suc (Min S)}))" using34by auto have6: "sorted_list_of_set (Suc ` S) = Suc (Min S)#(set_to_list (Suc ` (S - {Min S})))" by (metis (no_types, lifting) "0""5" Diff_insert_absorb image_insert inj_Suc inj_on_insert) show ?case using6 by (simp add: "1""2") qed thus ?thesis using n_def by blast qed
lemma nth_elem_Suc_im: assumes"i < card S" shows"nth_elem (Suc ` S) i = Suc (nth_elem S i) " using set_to_list_Suc_map by (metis assms card_ge_0_finite dual_order.strict_trans not_gr0 nth_elem.elims nth_map set_to_list_length)
lemma set_to_list_upto: "set_to_list {..<n} = [0..<n]" by (simp add: lessThan_atLeast0)
lemma nth_elem_upto: assumes"i < n" shows"nth_elem {..<n} i = i" using set_to_list_upto by (simp add: assms)
text‹Characterizing the entries of project\_at\_indices ›
lemma project_at_indices_append: "project_at_indices S (as@bs) = project_at_indices S as @ project_at_indices {j. j + length as ∈ S} bs" using nths_append[of as bs S] by auto
lemma project_at_indices_nth: assumes"S ⊆ indices_of as" assumes"card S > i" shows"project_at_indices S as ! i = as ! (nth_elem S i)" proof- have"∧ S i. S ⊆ indices_of as ∧ card S > i ==> project_at_indices S as ! i = as ! (nth_elem S i)" proof(induction as) case Nil thenshow ?case by (metis list.size(3) not_less0 nths_nil proj_at_index_list_length) next case (Cons a as) assume A: "S ⊆ indices_of (a # as) ∧ i < card S" have0: "nths (a # as) S = (if 0 ∈ S then [a] else []) @ nths as {j. Suc j ∈ S}" using nths_Cons[of a as S] by simp show"nths (a # as) S ! i = (a # as) ! nth_elem S i" proof(cases "0 ∈ S") case True show ?thesis proof(cases "S = {0}") case True thenshow ?thesis using"0" Cons.prems by auto next case False have T0: "nths (a # as) S = a#nths as {j. Suc j ∈ S}" using0 by (simp add: True) have T1: "{j. Suc j ∈ S} ⊆ indices_of as" prooffix x assume A: "x ∈ {j. Suc j ∈ S}" thenhave"Suc x < length (a#as)" using Cons.prems indices_of_def by blast thenshow"x ∈ indices_of as" by (simp add: indices_of_def) qed have T2: "∧i. i < card {j. Suc j ∈ S} ==> nths as {j. Suc j ∈ S} ! i = as ! nth_elem {j. Suc j ∈ S} i" using Cons.IH T1 by blast have T3: "∧i. i < card {j. Suc j ∈ S} ==> nth_elem {j. j > 0 ∧ j∈ S} i = nth_elem S (Suc i)" proof- have0: " 0 < card {j. Suc j ∈ S}" by (smt Cons.prems Diff_iff Diff_subset False T0 T1 True add_diff_cancel_left'
card.insert card_0_eq card.infinite finite_subset gr_zeroI insert_Diff
length_Cons n_not_Suc_n plus_1_eq_Suc proj_at_index_list_length singletonI) have1: "(insert 0 {j. 0 < j ∧ j ∈ S}) = S" apply(rule set_eqI) using True gr0I by blast have2: "0 < Min {j. 0 < j ∧ j ∈ S}"using False by (metis (mono_tags, lifting) "1" Cons.prems Min_in finite_insert finite_lessThan
finite_subset indices_of_def less_Suc_eq less_Suc_eq_0_disj mem_Collect_eq singleton_conv) show"∧i. i < card {j. Suc j ∈ S} ==> nth_elem {j. 0 < j ∧ j ∈ S} i = nth_elem S (Suc i)" using012 nth_elem_insert_Min[of "{j. 0 < j ∧ j ∈ S}"0] True False by (metis (no_types, lifting) Cons.prems T0 T1 card_gt_0_iff finite_insert length_Cons less_SucI proj_at_index_list_length) qed show"nths (a # as) S ! i = (a # as) ! nth_elem S i" apply(cases "i = 0") apply (metis Cons.prems Min_le T0 True card_ge_0_finite le_zero_eq nth_Cons' nth_elem_Min) proof- assume"i ≠ 0" thenhave"i = Suc (i - 1)" using Suc_pred' by blast hence"nths (a # as) S ! i = nths as {j. Suc j ∈ S} ! (i-1)" using A by (simp add: T0) thus"nths (a # as) S ! i = (a # as) ! nth_elem S i" proof- have"i - 1 < card {j. Suc j ∈ S}" by (metis Cons.prems Suc_less_SucD T0 T1 ‹i = Suc (i - 1)› length_Cons proj_at_index_list_length) hence0: "nth_elem {j. 0 < j ∧ j ∈ S} (i - 1) = nth_elem S i" using T3[of "i-1"] ‹i = Suc (i - 1)›by auto
have1: "nths as {j. Suc j ∈ S} ! (i-1) = as ! nth_elem {j. Suc j ∈ S} (i-1)" using T2 ‹i - 1 < card {j. Suc j ∈ S}›by blast have2: "(a # as) ! nth_elem S i = as! ((nth_elem S i) - 1)" by (metis Cons.prems ‹i = Suc (i - 1)› not_less0 nth_Cons' nth_elem_Suc) have3: "(nth_elem S i) - 1 = nth_elem {j. Suc j ∈ S} (i-1)" proof- have"Suc ` {j. Suc j ∈ S} = {j. 0 < j ∧ j ∈ S}" proof show"Suc ` {j. Suc j ∈ S} ⊆ {j. 0 < j ∧ j ∈ S}" by blast show"{j. 0 < j ∧ j ∈ S} ⊆ Suc ` {j. Suc j ∈ S}" using Suc_pred gr0_conv_Suc by auto qed thus ?thesis using"0"‹i - 1 < card {j. Suc j ∈ S}› nth_elem_Suc_im by fastforce qed show"nths (a # as) S ! i = (a # as) ! nth_elem S i" using"1""2""3"‹nths (a # as) S ! i = nths as {j. Suc j ∈ S} ! (i - 1)›by auto qed qed qed next case False have F0: "nths (a # as) S = nths as {j. Suc j ∈ S}" by (simp add: "0" False) have F1: "Suc `{j. Suc j ∈ S} = S" proofshow"Suc ` {j. Suc j ∈ S} ⊆ S"by auto show"S ⊆ Suc ` {j. Suc j ∈ S}"using False Suc_pred by (smt image_iff mem_Collect_eq neq0_conv subsetI) qed have F2: "{j. Suc j ∈ S} ⊆ indices_of as ∧ i < card {j. Suc j ∈ S}" using F1 by (metis (mono_tags, lifting) A F0 Suc_less_SucD indices_of_def length_Cons lessThan_iff
mem_Collect_eq proj_at_index_list_length subset_iff) have F3: "project_at_indices {j. Suc j ∈ S} as ! i = as ! (nth_elem {j. Suc j ∈ S} i)" using F2 Cons(1)[of "{j. Suc j ∈ S}"] Cons(2) by blast thenshow ?thesis using F0 F1 F2 nth_elem_Suc_im by fastforce qed qed thenshow ?thesis using assms(1) assms(2) by blast qed
text‹An inverse for nth\_elem›
definition set_rank where "set_rank S x = (THE i. i < card S ∧ x = nth_elem S i)"
lemma set_rank_exist: assumes"finite S" assumes"x ∈ S" shows"∃i. i < card S ∧ x = nth_elem S i" using assms nth_elem.simps[of S] by (metis in_set_conv_nth set_to_list_length sorted_list_of_set(1))
lemma set_rank_unique: assumes"finite S" assumes"x ∈ S" assumes"i < card S ∧ x = nth_elem S i" assumes"j < card S ∧ x = nth_elem S j" shows"i = j" using assms nth_elem.simps[of S] by (simp add: ‹i < card S ∧ x = nth_elem S i›‹j < card S ∧ x = nth_elem S j›
nth_eq_iff_index_eq set_to_list_length)
lemma nth_elem_set_rank_inv: assumes"finite S" assumes"x ∈ S" shows"nth_elem S (set_rank S x) = x" using the_equality set_rank_unique set_rank_exist assms unfolding set_rank_def by smt
lemma set_rank_nth_elem_inv: assumes"finite S" assumes"i < card S" shows"set_rank S (nth_elem S i) = i" using the_equality set_rank_unique set_rank_exist assms unfolding set_rank_def proof - show"(THE n. n < card S ∧ nth_elem S i = nth_elem S n) = i" using assms(1) assms(2) nth_elem_closed set_rank_unique by blast qed
lemma set_rank_range: assumes"finite S" assumes"x ∈ S" shows"set_rank S x < card S" using assms(1) assms(2) set_rank_exist set_rank_nth_elem_inv by fastforce
lemma project_at_indices_nth': assumes"S ⊆ indices_of as" assumes"i ∈ S" shows"as ! i = project_at_indices S as ! (set_rank S i) " by (metis assms(1) assms(2) finite_lessThan finite_subset indices_of_def nth_elem_set_rank_inv
project_at_indices_nth set_rank_range)
fun proj_away_from_index :: "nat ==> 'a list ==> 'a list" (‹π≠_›)where "proj_away_from_index n as = (take n as)@(drop (Suc n) as)"
text‹proj\_away\_from\_index is an inverse to insert\_at\_index›
lemma insert_at_index_project_away[simp]: assumes"k < length as" assumes"bs = (insert_at_index as a k)" shows"π<noteq> k bs = as" using assms insert_at_index.simps[of as a k] proj_away_from_index.simps[of k bs] by (simp add: ‹k < length as› less_imp_le_nat min.absorb2)
definition fibred_cell :: "'a list set ==> ('a list ==> 'a ==> bool) ==> 'a list set"where "fibred_cell C P = {as . ∃x t. as = (t#x) ∧ x ∈ C ∧ (P x t)}"
definition fibred_cell_at_ind :: "nat ==> 'a list set ==> ('a list ==> 'a ==> bool)==> 'a list set"where "fibred_cell_at_ind n C P = {as . ∃x t. as = (insert_at_index x t n) ∧ x ∈ C ∧ (P x t)}"
lemma fibred_cell_lengths: assumes"∧k. k ∈ C ==> length k = n" shows"k ∈ (fibred_cell C P) ==> length k = Suc n" proof- assume"k ∈ (fibred_cell C P)" obtain x t where"k = (t#x) ∧ x ∈ C ∧ P x t" proof - assume a1: "∧t x. k = t # x ∧ x ∈ C ∧ P x t ==> thesis" have"∃as a. k = a # as ∧ as ∈ C ∧ P as a" using‹k ∈ fibred_cell C P› fibred_cell_def by blast thenshow ?thesis using a1 by blast qed thenshow ?thesis by (simp add: assms) qed
lemma fibred_cell_at_ind_lengths: assumes"∧k. k ∈ C ==> length k = n" assumes"k ≤ n" shows"c ∈ (fibred_cell_at_ind k C P) ==> length c = Suc n" proof- assume"c ∈ (fibred_cell_at_ind k C P)" thenobtain x t where"c = (insert_at_index x t k) ∧ x ∈ C ∧ (P x t)" using assms unfolding fibred_cell_at_ind_def by blast thenshow ?thesis by (simp add: assms(1)) qed
lemma project_fibred_cell: assumes"∧k. k ∈ C ==> length k = n" assumes"k < n" assumes"∀x ∈ C. ∃t. P x t" shows"π<noteq> k ` (fibred_cell_at_ind k C P) = C" proof show"π<noteq>k ` fibred_cell_at_ind k C P ⊆ C" proof fix x assume x_def: "x ∈ π<noteq>k ` fibred_cell_at_ind k C P" thenobtain c where c_def: "x = π<noteq>k c ∧ c ∈ fibred_cell_at_ind k C P" by blast thenobtain y t where yt_def: "c = (insert_at_index y t k) ∧ y ∈ C ∧ (P y t)" using assms unfolding fibred_cell_at_ind_def by blast have0: "x =π<noteq>k c" by (simp add: c_def) have1: "y =π<noteq>k c" using yt_def assms(1) assms(2) by (metis insert_at_index_project_away) have2: "x = y"using01by auto thenshow"x ∈ C" by (simp add: yt_def) qed show"C ⊆ π<noteq>k ` fibred_cell_at_ind k C P" prooffix x assume A: "x ∈ C" obtain t where t_def: "P x t" using assms A by auto thenshow"x ∈ π<noteq>k ` fibred_cell_at_ind k C P" proof - have f1: "∀a n A as. take n as @ (a::'a) # drop n as ∉ A ∨ as ∈ π<noteq>n ` A ∨¬ n < length as" by (metis insert_at_index.simps insert_at_index_project_away rev_image_eqI) have"∀n. ∃as a. take n x @ t # drop n x = insert_at_index as a n ∧ as ∈ C ∧ P as a" using A t_def by auto thenhave"∀n. take n x @ t # drop n x ∈ {insert_at_index as a n |as a. as ∈ C ∧ P as a}" by blast thenhave"x ∈ π<noteq>k ` {insert_at_index as a k |as a. as ∈ C ∧ P as a}" using f1 by (metis (lifting) A assms(1) assms(2)) thenshow ?thesis by (simp add: fibred_cell_at_ind_def) qed qed qed
definition list_segment where "list_segment i j as = map (nth as) [i..<j]"
lemma list_segment_length: assumes"i ≤ j" assumes"j ≤ length as" shows"length (list_segment i j as) = j - i" using assms unfolding list_segment_def by (metis length_map length_upt)
lemma list_segment_drop: assumes"i < length as" shows"(list_segment i (length as) as) = drop i as" by (metis One_nat_def Suc_diff_Suc add_diff_inverse_nat drop0 drop_map drop_upt
less_Suc_eq list_segment_def map_nth neq0_conv not_less0 plus_1_eq_Suc)
lemma list_segment_concat: assumes"j ≤ k" assumes"i ≤ j" shows"(list_segment i j as) @ (list_segment j k as) = (list_segment i k as)" using assms unfolding list_segment_def using le_Suc_ex upt_add_eq_append by fastforce
lemma list_segment_subset: assumes"j ≤ k" shows"set (list_segment i j as) ⊆ set (list_segment i k as)" apply(cases "i > j") unfolding list_segment_def apply (metis in_set_conv_nth length_map list.size(3) order.asym subsetI upt_rec zero_order(3)) proof- assume"¬ j < i" thenhave"i ≤j" using not_le by blast thenhave"list_segment i j as @ list_segment j k as = list_segment i k as" using assms list_segment_concat[of j k i as] by auto thenshow"set (map ((!) as) [i..<j]) ⊆ set (map ((!) as) [i..<k])" using set_append unfolding list_segment_def by (metis Un_upper1) qed
lemma list_segment_subset_list_set: assumes"j ≤ length as" shows"set (list_segment i j as) ⊆ set as" apply(cases "i ≥ j") apply (simp add: list_segment_def) proof- assume A: "¬ j ≤ i" thenhave B: "i < j" by auto have0: "list_segment i (length as) as = drop i as" using B assms list_segment_drop[of i as] less_le_trans by blast have1: "set (list_segment i j as) ⊆ set (list_segment i (length as) as)" using B assms list_segment_subset[of j "length as" i as] by blast thenshow ?thesis using assms 0 dual_order.trans set_drop_subset[of i as] by metis 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.