diff -r b3502f81ab3d -r cbf9f856d3e0 src/HOL/Library/Sublist.thy --- a/src/HOL/Library/Sublist.thy Fri Feb 28 11:36:59 2025 +0100 +++ b/src/HOL/Library/Sublist.thy Fri Feb 28 13:50:18 2025 +0000 @@ -63,11 +63,9 @@ subsection \Basic properties of prefixes\ -(* FIXME rm *) theorem Nil_prefix [simp]: "prefix [] xs" by (fact prefix_bot.bot_least) -(* FIXME rm *) theorem prefix_Nil [simp]: "(prefix xs []) = (xs = [])" by (fact prefix_bot.bot_unique) @@ -80,7 +78,7 @@ next assume "xs = ys @ [y] \ prefix xs ys" then show "prefix xs (ys @ [y])" - by auto (metis append.assoc prefix_def) + using prefix_def prefix_order.order_trans by blast qed lemma Cons_prefix_Cons [simp]: "prefix (x # xs) (y # ys) = (x = y \ prefix xs ys)" @@ -109,23 +107,26 @@ theorem prefix_append: "prefix xs (ys @ zs) = (prefix xs ys \ (\us. xs = ys @ us \ prefix us zs))" - apply (induct zs rule: rev_induct) - apply force - apply (simp flip: append_assoc) - apply (metis append_eq_appendI) - done +proof (induct zs rule: rev_induct) + case Nil + then show ?case by force +next + case (snoc x xs) + then show ?case + by (metis append.assoc prefix_snoc) +qed lemma append_one_prefix: "prefix xs ys \ length xs < length ys \ prefix (xs @ [ys ! length xs]) ys" - proof (unfold prefix_def) - assume a1: "\zs. ys = xs @ zs" - then obtain sk :: "'a list" where sk: "ys = xs @ sk" by fastforce - assume a2: "length xs < length ys" - have f1: "\v. ([]::'a list) @ v = v" using append_Nil2 by simp - have "[] \ sk" using a1 a2 sk less_not_refl by force - hence "\v. xs @ hd sk # v = ys" using sk by (metis hd_Cons_tl) - thus "\zs. ys = (xs @ [ys ! length xs]) @ zs" using f1 by fastforce - qed +proof (unfold prefix_def) + assume a1: "\zs. ys = xs @ zs" + then obtain sk :: "'a list" where sk: "ys = xs @ sk" by fastforce + assume a2: "length xs < length ys" + have f1: "\v. ([]::'a list) @ v = v" using append_Nil2 by simp + have "[] \ sk" using a1 a2 sk less_not_refl by force + hence "\v. xs @ hd sk # v = ys" using sk by (metis hd_Cons_tl) + thus "\zs. ys = (xs @ [ys ! length xs]) @ zs" using f1 by fastforce +qed theorem prefix_length_le: "prefix xs ys \ length xs \ length ys" by (auto simp add: prefix_def) @@ -148,7 +149,7 @@ unfolding prefix_def by (metis takeWhile_dropWhile_id) lemma prefixeq_butlast: "prefix (butlast xs) xs" -by (simp add: butlast_conv_take take_is_prefix) + by (simp add: butlast_conv_take take_is_prefix) lemma prefix_map_rightE: assumes "prefix xs (map f ys)" @@ -162,13 +163,13 @@ qed lemma map_mono_prefix: "prefix xs ys \ prefix (map f xs) (map f ys)" -by (auto simp: prefix_def) + by (auto simp: prefix_def) lemma filter_mono_prefix: "prefix xs ys \ prefix (filter P xs) (filter P ys)" -by (auto simp: prefix_def) + by (auto simp: prefix_def) lemma sorted_antimono_prefix: "prefix xs ys \ sorted ys \ sorted xs" -by (metis sorted_append prefix_def) + by (metis sorted_append prefix_def) lemma prefix_length_less: "strict_prefix xs ys \ length xs < length ys" by (auto simp: strict_prefix_def prefix_def) @@ -281,8 +282,8 @@ subsection \Prefixes\ primrec prefixes where -"prefixes [] = [[]]" | -"prefixes (x#xs) = [] # map ((#) x) (prefixes xs)" + "prefixes [] = [[]]" | + "prefixes (x#xs) = [] # map ((#) x) (prefixes xs)" lemma in_set_prefixes[simp]: "xs \ set (prefixes ys) \ prefix xs ys" proof (induct xs arbitrary: ys) @@ -400,44 +401,43 @@ lemma Longest_common_prefix_unique: \\! ps. (\xs \ L. prefix ps xs) \ (\qs. (\xs \ L. prefix qs xs) \ length qs \ length ps)\ if \L \ {}\ - using that apply (rule ex_ex1I[OF Longest_common_prefix_ex]) - using that apply (auto simp add: prefix_def) - apply (metis append_eq_append_conv_if order.antisym) - done + apply (intro ex_ex1I[OF Longest_common_prefix_ex [OF that]]) + by (meson that all_not_in_conv prefix_length_prefix prefix_order.dual_order.eq_iff) lemma Longest_common_prefix_eq: - "\ L \ {}; \xs \ L. prefix ps xs; + "\ L \ {}; \xs \ L. prefix ps xs; \qs. (\xs \ L. prefix qs xs) \ size qs \ size ps \ \ Longest_common_prefix L = ps" -unfolding Longest_common_prefix_def arg_max_def is_arg_max_linorder -by(rule some1_equality[OF Longest_common_prefix_unique]) auto + unfolding Longest_common_prefix_def arg_max_def is_arg_max_linorder + by(rule some1_equality[OF Longest_common_prefix_unique]) auto lemma Longest_common_prefix_prefix: "xs \ L \ prefix (Longest_common_prefix L) xs" -unfolding Longest_common_prefix_def arg_max_def is_arg_max_linorder -by(rule someI2_ex[OF Longest_common_prefix_ex]) auto + unfolding Longest_common_prefix_def arg_max_def is_arg_max_linorder + by(rule someI2_ex[OF Longest_common_prefix_ex]) auto lemma Longest_common_prefix_longest: "L \ {} \ \xs\L. prefix ps xs \ length ps \ length(Longest_common_prefix L)" -unfolding Longest_common_prefix_def arg_max_def is_arg_max_linorder -by(rule someI2_ex[OF Longest_common_prefix_ex]) auto + unfolding Longest_common_prefix_def arg_max_def is_arg_max_linorder + by(rule someI2_ex[OF Longest_common_prefix_ex]) auto lemma Longest_common_prefix_max_prefix: "L \ {} \ \xs\L. prefix ps xs \ prefix ps (Longest_common_prefix L)" -by(metis Longest_common_prefix_prefix Longest_common_prefix_longest - prefix_length_prefix ex_in_conv) + by(metis Longest_common_prefix_prefix Longest_common_prefix_longest + prefix_length_prefix ex_in_conv) lemma Longest_common_prefix_Nil: "[] \ L \ Longest_common_prefix L = []" -using Longest_common_prefix_prefix prefix_Nil by blast + using Longest_common_prefix_prefix prefix_Nil by blast -lemma Longest_common_prefix_image_Cons: "L \ {} \ - Longest_common_prefix ((#) x ` L) = x # Longest_common_prefix L" -apply(rule Longest_common_prefix_eq) - apply(simp) - apply (simp add: Longest_common_prefix_prefix) -apply simp -by(metis Longest_common_prefix_longest[of L] Cons_prefix_Cons Nitpick.size_list_simp(2) - Suc_le_mono hd_Cons_tl order.strict_implies_order zero_less_Suc) +lemma Longest_common_prefix_image_Cons: + assumes "L \ {}" + shows "Longest_common_prefix ((#) x ` L) = x # Longest_common_prefix L" +proof (intro Longest_common_prefix_eq strip) + show "\qs. \xs\(#) x ` L. prefix qs xs \ + length qs \ length (x # Longest_common_prefix L)" + by (metis assms Longest_common_prefix_longest[of L] Cons_prefix_Cons Suc_le_mono hd_Cons_tl + image_eqI length_Cons prefix_bot.bot_least prefix_length_le) +qed (auto simp add: assms Longest_common_prefix_prefix) lemma Longest_common_prefix_eq_Cons: assumes "L \ {}" "[] \ L" "\xs\L. hd xs = x" shows "Longest_common_prefix L = x # Longest_common_prefix {ys. x#ys \ L}" @@ -450,26 +450,26 @@ lemma Longest_common_prefix_eq_Nil: "\x#ys \ L; y#zs \ L; x \ y \ \ Longest_common_prefix L = []" -by (metis Longest_common_prefix_prefix list.inject prefix_Cons) + by (metis Longest_common_prefix_prefix list.inject prefix_Cons) fun longest_common_prefix :: "'a list \ 'a list \ 'a list" where -"longest_common_prefix (x#xs) (y#ys) = + "longest_common_prefix (x#xs) (y#ys) = (if x=y then x # longest_common_prefix xs ys else [])" | -"longest_common_prefix _ _ = []" + "longest_common_prefix _ _ = []" lemma longest_common_prefix_prefix1: "prefix (longest_common_prefix xs ys) xs" -by(induction xs ys rule: longest_common_prefix.induct) auto + by(induction xs ys rule: longest_common_prefix.induct) auto lemma longest_common_prefix_prefix2: "prefix (longest_common_prefix xs ys) ys" -by(induction xs ys rule: longest_common_prefix.induct) auto + by(induction xs ys rule: longest_common_prefix.induct) auto lemma longest_common_prefix_max_prefix: "\ prefix ps xs; prefix ps ys \ \ prefix ps (longest_common_prefix xs ys)" -by(induction xs ys arbitrary: ps rule: longest_common_prefix.induct) - (auto simp: prefix_Cons) + by(induction xs ys arbitrary: ps rule: longest_common_prefix.induct) + (auto simp: prefix_Cons) subsection \Parallel lists\ @@ -506,10 +506,7 @@ qed lemma parallel_append: "a \ b \ a @ c \ b @ d" - apply (rule parallelI) - apply (erule parallelE, erule conjE, - induct rule: not_prefix_induct, simp+)+ - done + by (meson parallelE parallelI prefixI prefix_order.trans prefix_same_cases) lemma parallel_appendI: "xs \ ys \ x = xs @ xs' \ y = ys @ ys' \ x \ y" by (simp add: parallel_append) @@ -1265,31 +1262,13 @@ by (auto simp: sublist_def intro: exI[of _ "[]"]) lemma sublist_append_rightI [simp, intro]: "sublist xs (xs @ ss)" - by (auto simp: sublist_def intro: exI[of _ "[]"]) + by (metis append_eq_append_conv2 sublist_appendI) lemma sublist_altdef: "sublist xs ys \ (\ys'. prefix ys' ys \ suffix xs ys')" -proof safe - assume "sublist xs ys" - then obtain ps ss where "ys = ps @ xs @ ss" by (auto simp: sublist_def) - thus "\ys'. prefix ys' ys \ suffix xs ys'" - by (intro exI[of _ "ps @ xs"] conjI suffix_appendI) auto -next - fix ys' - assume "prefix ys' ys" "suffix xs ys'" - thus "sublist xs ys" by (auto simp: prefix_def suffix_def) -qed + by (metis append_assoc prefix_def sublist_def suffix_def) lemma sublist_altdef': "sublist xs ys \ (\ys'. suffix ys' ys \ prefix xs ys')" -proof safe - assume "sublist xs ys" - then obtain ps ss where "ys = ps @ xs @ ss" by (auto simp: sublist_def) - thus "\ys'. suffix ys' ys \ prefix xs ys'" - by (intro exI[of _ "xs @ ss"] conjI suffixI) auto -next - fix ys' - assume "suffix ys' ys" "prefix xs ys'" - thus "sublist xs ys" by (auto simp: prefix_def suffix_def) -qed + by (metis prefixE prefixI sublist_appendI sublist_def suffixE suffixI) lemma sublist_Cons_right: "sublist xs (y # ys) \ prefix xs (y # ys) \ sublist xs ys" by (auto simp: sublist_def prefix_def Cons_eq_append_conv) @@ -1453,8 +1432,8 @@ qed private lemma list_emb_primrec: - "list_emb = (\uu uua uuaa. rec_list (\P xs. List.null xs) (\y ys ysa P xs. case xs of [] \ True - | x # xs \ if P x y then ysa P xs else ysa P (x # xs)) uuaa uu uua)" + "list_emb = (\uu l' l. rec_list (\P xs. List.null xs) (\y ys ysa P xs. case xs of [] \ True + | x # xs \ if P x y then ysa P xs else ysa P (x # xs)) l uu l')" proof (intro ext, goal_cases) case (1 P xs ys) show ?case