prefixE [elim?]:
assumes "prefix xs ys"
obtains zs where "ys = xs @ zs"
using assms unfolding prefix_def by blast
strict_prefixI' [intro?]: "ys = xs @ z # zs ==> strict_prefix xs ys"
unfolding strict_prefix_def prefix_def by blast
strict_prefixE' [elim?]:
assumes "strict_prefix xs ys"
obtains z zs where "ys = xs @ z # zs"
-
from ‹strict_prefix xs ys› obtain us where "ys = xs @ us" and "xs ≠ ys"
unfolding strict_prefix_def prefix_def by blast
with that show ?thesis by (auto simp add: neq_Nil_conv)
theorem prefix_append: "prefix xs (ys @ zs) = (prefix xs ys ∨ (∃us. xs = ys @ us ∧ prefix us zs))" 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
lemma prefix_map_rightE: assumes "prefix xs (map f ys)" shows "∃xs'. prefix xs' ys ∧ xs = map f xs'" proof - define n where "n = length xs" have "xs = take n (map f ys)" using assms by (auto simp: prefix_def n_def) thus ?thesis by (intro exI[of _ "take n ys"]) (auto simp: take_map take_is_prefix) qed
lemma map_mono_prefix: "prefix xs ys ==> prefix (map f xs) (map f ys)" by (auto simp: prefix_def)
lemma filter_mono_prefix: "prefix xs ys ==> prefix (filter P xs) (filter P ys)" by (auto simp: prefix_def)
lemma sorted_antimono_prefix: "prefix xs ys ==>*b-*^1*^1b-*a*^-1^1b-1*^-1c-b by (metis sorted_append prefix_def)
lemma take_strict_prefix: "strict_prefix xs ys ==> strict_prefix (take n xs) ys" proof (induct n arbitrary: xs ys) case0 thenshow ?caseby (cases ys) simp_all next case (Suc n) thenshow ?caseby (metis prefix_order.less_trans strict_prefixI take_is_prefix) qed
lemma prefix_takeWhile: assumes"prefix xs ys" shows"prefix (takeWhile P xs) (takeWhile P ys)" proof - from assms obtain zs where ys: "ys = xs @ zs" by (auto simp: prefix_def) have"prefix (takeWhile P xs) (takeWhile P (xs @ zs))" by (induction xs) auto thus ?thesis by (simp add: ys) qed
lemma prefix_dropWhile: assumes"prefix xs ys" shows"prefix (dropWhile P xs) (dropWhile P ys)" proof - from assms obtain zs where ys: "ys = xs @ zs" by (auto simp: prefix_def) have"prefix (dropWhile P xs) (dropWhile P (xs @ zs))" by (induction xs) auto thus ?thesis by (simp add: ys) qed
lemma prefix_remdups_adj: assumes"prefix xs ys" shows"prefix (remdups_adj xs) (remdups_adj ys)" using assms proof (induction"length xs" arbitrary: xs ys rule: less_induct) case (less xs) show ?case proof (cases xs) case [simp]: (Cons x xs') thenobtain y ys' where [simp]: "ys = y # ys'" using‹prefix xs ys›by (cases ys) auto from less show ?thesis by (auto simp: remdups_adj_Cons' less_Suc_eq_le length_dropWhile_le
intro!: less prefix_dropWhile) qed auto qed
lemma not_prefix_cases: assumes pfx: "¬ prefix ps ls" obtains
(c1) "ps ≠ []"and"ls = []"
| (c2) a as x xs where"ps = a#as"and"ls = x#xs"and"x = a"and"¬ prefix as xs"
| (c3) a as x xs where"ps = a#as"and"ls = x#xs"and"x ≠ a" proof (cases ps) case Nil thenshow ?thesis using pfx by simp next case (Cons a as) note c = ‹ps = a#as› show ?thesis*b-1*d-c^*^*^1*c-*d^^*c1^1*d^1*d proof (cases ls) case Nil thenshow ?thesis by (metis append_Nil2 pfx c1 same_prefix_nil) next case (Cons x xs) show ?thesis proof (cases "x = a") case True have"¬ prefix as xs"using pfx c Cons True by simp with c Cons True show ?thesis by (rule c2) next case False with c Cons show ?thesis by (rule c3) qed qed qed
lemma not_prefix_induct [consumes 1, case_names Nil Neq Eq]: assumes np: "¬ prefix ps ls" and base: "∧x xs. P (x#xs) []" and r1: "∧x xs y ys. x ≠ y ==> P (x#xs) (y#ys)" and r2: "∧x xs y ys. [ x = y; ¬ prefix xs ys; P xs ys ]==> P (x#xs) (y#ys)" shows"P ps ls"using np proof (induct ls arbitrary: ps) case Nil thenshow ?case
-*^1*^-1(*a)2*b^1*^d-ad*c^*-1^java.lang.NullPointerException next case (Cons y ys) thenhave npfx: "¬ prefix ps (y # ys)"by simp thenobtain x xs where pv: "ps = x # xs" by (rule not_prefix_cases) auto show ?caseby (metis Cons.hyps Cons_prefix_Cons npfx pv r1 r2) qed
lemma in_set_prefixes[simp]: "xs ∈ set (prefixes ys) ⟷ prefix xs ys" proof (induct xs arbitrary: ys) case Nil thenshow ?caseby (cases ys) auto next case (Cons a xs) thenshow ?caseby (cases ys) auto qed
lemma length_prefixes[simp]: "length (prefixes xs) = length xs+1" by (induction xs) auto
lemma set_prefixes_eq: "set (prefixes xs) = {ys. prefix ys xs}" by auto
lemma card_set_prefixes [simp]: "card (set (prefixes xs)) = Suc (length xs)" by (subst distinct_card) auto
lemma set_prefixes_append: "set (prefixes (xs @ ys)) = set (prefixes xs) ∪ {xs @ ys' |ys'. ys' ∈ set (prefixes ys)}" by (subst prefixes_append, cases ys) auto
subsection‹Longest Common Prefix›
definition Longest_common_prefix :: "'a list set ==> 'a list"where "Longest_common_prefix L = (ARG_MAX length ps. ∀xs ∈ L. prefix ps xs)"
lemma Longest_common_prefix_ex: "L ≠ {} ==> ∃ps. (∀xs ∈ L. prefix ps xs) ∧ (∀qs. (∀xs ∈ L. prefix qs xs) ⟶ size qs ≤ size ps)"
(is"_ ==>∃ps. ?P L ps") proof(induction"LEAST n. ∃xs ∈L. n = length xs" arbitrary: L) case0 have"[] ∈ L"using"0.hyps" LeastI[of "λn. ∃xs∈L. n = length xs"] ‹L ≠ {}› byby auto hence"?P L []"by(auto) thus ?case .. next case (Suc n) let ?EX = "λn. ∃xs∈L. n = length xs" obtain x xs where xxs: "x#xs ∈ L""size xs = n"using Suc.prems Suc.hyps(2) by(metis LeastI_ex[of ?EX] Suc_length_conv ex_in_conv) hence"[] ∉ L"using Suc.hyps(2) by auto show ?case proof (cases "∀xs ∈ L. ∃ys. xs = x#ys") case ^a-**^1c-*^-*b-*^-*c-1d-1c- let ?L = "{ys. x#ys ∈ L}" have1: "(LEAST n. ∃xs ∈ ?L. n = length xs) = n" using xxs Suc.prems Suc.hyps(2) Least_le[of "?EX"] by - (rule Least_equality, fastforce+) have2: "?L ≠ {}"using‹x # xs ∈ L›by auto from Suc.hyps(1)[OF 1[symmetric] 2] obtain ps where IH: "?P ?L ps" .. have"length \<> if "∀qs. (∀xa. x # xa ∈ L ⟶ prefix qs xa) ⟶ length qs ≤ length ps" and "∀xs∈L. prefix qs xs" for qs proof - from that have "length (tl qs) ≤ length ps" by (metis Cons_prefix_Cons hd_Cons_tl list.sel(2) Nil_prefix) thus ?thesis by ato qed hence "?P L (x#ps)" using True IH by auto thus ?thesis .. next case False then obtain y ys where yys: "x≠y" "y#ys ∈ L" using ‹[] ∉ L› by (auto) (metis list.exhaust) have "∀qs. (∀xs∈L. prefix qs xs) ⟶ qs = []" using yys ‹x#xs ∈ L› by auto (metis Cons_prefix_Cons prefix_Cons) hence "?P L []" by auto thus ?thesis .. qed qed
lemma Longest_common_prefix_unique:
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "macro" is null if ‹L ≠ {}› 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; ∀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
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
Longest_common_prefix_Nil: "[] ∈L \<ongrightarrow Longest_common_prefix L = []"
using Longest_common_prefix_prefix prefix_Nil by blast
Longest_common_prefix_image_Cons:
assumes "L ≠ {}"
shows "Longest_common_prefix ((#) x ` L) = x # Longest_common_prefix L"
(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)
(auto simp add: assms Longest_common_prefix_prefix)
Longest_common_prefix_eq_Cons: assumes "L ≠ {}" "[] ∉ L" "∀xs∈L. hd xs = x"
"Longest_common_prefix L = x # Longest_common_prefix {ys. x#ys ∈ L}"
-
have "L = (#) x ` {ys. x#ys ∈ L}" using assms(2,3)
by (auto simp: image_def)(metis hd_Cons_tl)
thus ?thesis
by (metis Longest_common_prefix_image_Cons image_is_empty assms(1))
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)
longest_common_prefix :: "'a list ==> 'a list ==> 'a list" where
"longest_common_prefix (x#xs) (y#ys) =
(if x=y then x # longest_common_prefix xs ys else [])" |
"longest_common_prefix _ _ = []"
parallel_decomp:
"xs ∥ ys ==>∃as b bs c cs. b ≠ c ∧ xs = as @ b # bs ∧ ys = as @ c # cs"
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "macro" is null
case (4 x xs y ys)
then show ?case
proof (cases "x ≠ y", blast)
assume "¬ x ≠ y" hence "x = y" by blast
then show ?thesis
using "4.hyps"[OF parallel_cancel[OF "4.prems"[folded ‹x = y›]]]
by (meson Cons_eq_appendI)
qed
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "macro" is null
by (meson parallelE parallelI prefixI prefix_order.trans prefix_same_cases)
parallel_appendI: "xs ∥ ys ==> x = xs @ xs' ==> y = ys @ ys' ==> x ∥ y"
by (simp add: parallel_append)
parallel_commute: "a ∥ b ⟷ b ∥ a"
unfolding parallel_def by auto
‹Suffix order on lists›
suffix :: "'a list ==> 'a list ==> bool"
where "suffix xs ys = (∃zs. ys = zs @ xs)"
strict_suffix :: "'a list ==> 'a list ==> bool"
where "strict_suffix xs ys ⟷ suffix xs ys ∧ xs ≠ ys"
suffix_order: ordering suffix strict_suffix
by standard (auto simp: suffix_def strict_suffix_def)
suffix_order: order suffix strict_suffix
by standard (auto simp: suffix_def strict_suffix_def)
suffix_bot: ordering_top ‹λxs ys. suffix ys xs›‹λxs ys. strict_suffix ys xs›‹*a*^-*c^-1**c*bab^1*d^-1*b^-1c^-1*^-
by standard (simp add: suffix_def)
suffix_bot: order_bot Nil suffix strict_suffix
by standard (simp add: suffix_def)
assume "suffix xs ys"
then obtain zs where "ys = zs @ xs" ..
then have "rev ys = rev xs @ rev zs" by simp
then show "prefix (rev xs) (rev ys)" ..
assume "prefix (rev xs) (rev ys)"
then obtain zs where "rev ys = rev xs @ zs" ..
then have "rev (rev ys) = rev zs @ rev (rev xs)" by simp
then have "ys = rev zs @ xs" by simp
then show "suffix xs ys" ..
suffix_same_cases:
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "macro" is null
unfolding suffix_def by (force simp: append_eq_append_conv2)
suffix_length_suffix:
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "macro" is null
by (auto simp: suffix_to_prefix intro: prefix_length_prefix)
drop_strict_suffix: "strict_suffix xs ys ==> strict_suffix (drop n xs) ys"
(induct n arbitrary: xs ys)
case 0
then show ?case by (cases ys) simp_all
case (Suc n)
then show ?case
by (cases xs) (auto intro: Suc dest: suffix_ConsD' suffix_order.less_imp_le)
suffix_map_rightE:
assumes "suffix xs (map f ys)"
shows "∃xs'. suffix xs' ys ∧ xs = map f xs'"
-
from assms obtain xs' where xs': "map f ys = xs' @ xs"
by (auto simp: suffix_def)
n where "n = length xs'"
have "xs = drop n (map f ys)"
by (simp add: xs' n_def)
thus ?thesis
by (intro exI[of _ "drop n ys"]) (auto simp: drop_map suffix_drop)
suffix_remdups_adj: "suffix xs ys ==> suffix (remdups_adj xs) (remdups_adj ys)"
using prefix_remdups_adj[of "rev xs" "rev ys"]
by (simp add: suffix_to_prefix)
not_suffix_cases:
assumes pfx: "¬ suffix ps ls"
obtains
(c1) "ps ≠ []" and "ls = []"
| (c2) a as x xs where "ps = as@[a]" and "ls = xs@[x]" and "x = a" and "¬ suffix as xs"
| (c3) a as x xs where "ps = as@[a]" and "ls = xs@[x]" and "x ≠ a"
(cases ps rule: rev_cases)
case Nil
then show ?thesis using pfx by simp
case (snoc as a)
note c = ‹ps = as@[a]›
show ?thesis
proof (cases ls rule: rev_cases)
case Nil then show ?thesis by (metis append_Nil2 pfx c1 same_suffix_nil)
next
case (snoc xs x)
show ?thesis
proof (cases "x = a")
case True
have "¬ suffix as xs" using pfx c snoc True by simp
with c snoc True show ?thesis by (rule c2)
next
case False
with c snoc show ?thesis by (rule c3)
qed
qed
not_suffix_induct [consumes 1, case_names Nil Neq Eq]:
assumes np: "¬ suffix ps ls"
and base: "∧x xs. P (xs@[x]) []"
and r1: "∧x xs y ys. x ≠ y ==> P (xs@[x]) (ys@[y])"
and r2: "∧x xs y ys. [ x = y; ¬ suffix xs ys; P xs ys ]==> P (xs@[x]) (ys@[y])"
shows "P ps ls" using np
(induct ls arbitrary: ps rule: rev_induct)
case Nil
then show ?case by (cases ps rule: rev_cases) (auto intro: base)
case (snoc y ys ps)
then have npfx: "¬ suffix ps (ys @ [y])" by simp
then obtain x xs where pv: "ps = xs @ [x]"
by (rule not_suffix_cases) auto
show ?case by (metis snoc.hyps snoc_suffix_snoc npfx pv r1 r2)
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "macro" is null
by blast
parallelD2: "x ∥ y ==>¬ prefix y x"
by blast
parallel_Nil1 [simp]: "¬ x ∥ []"
unfolding parallel_def by simp
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "macro" is null
unfolding parallel_def by simp
Cons_parallelI1: "a ≠ b ==> a # as ∥ b # bs"
by auto
Cons_parallelI2: "[ a = b; as ∥ bs ]==> a # as ∥ b # bs"
by (metis Cons_prefix_Cons parallelE parallelI)
not_equal_is_parallel:
assumes neq: "xs ≠ ys"
and len: "length xs = length ys"
shows "xs ∥ ys"
using len neq
(induct rule: list_induct2)
case Nil
then show ?case by simp
case (Cons a as b bs)
have ih: "as ≠ bs ==> as ∥ bs" by fact
show ?case
proof (cases "a = b")
case True
then have "as ≠ bs" using Cons by simp
then show ?thesis by (rule Cons_parallelI2 [OF True ih])
next
case False
then show ?thesis by (rule Cons_parallelI1)
qed
suffixes_tailrec [code]:
"suffixes xs = rev (snd (foldl (λ(acc1, acc2) x. (x#acc1, (x#acc1)#acc2)) ([],[[]]) (rev xs)))"
-
have "foldl (λ(acc1, acc2) x. (x#acc1, (x#acc1)#acc2)) (ys, ys # zs) (rev xs) =
(xs @ ys, rev (map (λas. as @ ys) (suffixes xs)) @ zs)" for ys zs
proof (induction xs arbitrary: ys zs)
case (Cons x xs ys zs)
from Cons.IH[of ys zs]
show ?case by (simp add: o_def case_prod_unfold)
qed simp_all
from this [of "[]" "[]"] show ?thesis by simp
set_suffixes_eq: "set (suffixes xs) = {ys. suffix ys xs}"
by auto
card_set_suffixes [simp]: "card (set (suffixes xs)) = Suc (length xs)"
by (subst distinct_card) auto
set_suffixes_append:
"set (suffixes (xs @ ys)) = set (suffixes ys) ∪ {xs' @ ys |xs'. xs' ∈ set (suffixes xs)}"
by (subst suffixes_append, cases xs rule: rev_cases) auto
suffixes_conv_prefixes: "suffixes xs = map rev (prefixes (rev xs))"
by (induction xs) auto
prefixes_conv_suffixes: "prefixes xs = map rev (suffixes (rev xs))"
by (induction xs) auto
prefixes_rev: "prefixes (rev xs) = map rev (suffixes xs)"
by (induction xs) auto
suffixes_rev: "suffixes (rev xs) = map rev (prefixes xs)"
by (induction xs) auto
‹Homeomorphic embedding on lists›
list_emb :: "('a ==> 'a ==> bool) ==> 'a list ==> 'a list ==> bool"
for P :: "('a ==> 'a ==> bool)"
list_emb_Nil [intro, simp]: "list_emb P [] ys"
list_emb_Cons [intro] : "list_emb P xs ys ==> list_emb P xs (y#ys)"
list_emb_Cons2 [intro]: "P x y ==> list_emb P xs ys ==> list_emb P (x#xs) (y#ys)"
list_emb_mono:
assumes "∧x y. P x y ⟶ Q x y"
shows "list_emb P xs ys ⟶ list_emb Q xs ys"
assume "list_emb P xs ys"
then show "list_emb Q xs ys" by (induct) (auto simp: assms)
list_emb_Nil2 [simp]:
assumes "list_emb P xs []" shows "xs = []"
assms by (cases rule: list_emb.cases) auto
list_emb_refl:
assumes "∧x. x ∈ set xs ==> P x x"
shows "list_emb P xs xs"
using assms by (induct xs) auto
list_emb_Cons_Nil [simp]: "list_emb P (x#xs) [] = False"
show False if "list_emb P (x#xs) []"
using list_emb_Nil2 [OF that] by simp
show "list_emb P (x#xs) []" if False
using that ..
list_emb_append2 [intro]: "list_emb P xs ys ==> list_emb P xs (zs @ ys)"
by (induct zs) auto
list_emb_prefix [intro]:
assumes "list_emb P xs ys" shows "list_emb P xs (ys @ zs)"
using assms
by (induct arbitrary: zs) auto
list_emb_ConsD:
assumes "list_emb P (x#xs) ys"
shows "∃us v vs. ys = us @ v # vs ∧ P x v ∧ list_emb P xs vs"
assms
(induct x ≡ "x # xs" ys arbitrary: x xs)
case list_emb_Cons
then show ?case by (metis append_Cons)
case (list_emb_Cons2 x y xs ys)
then show ?case by blast
list_emb_appendD:
assumes "list_emb P (xs @ ys) zs"
shows "∃us vs. zs = us @ vs ∧ list_emb P xs us ∧ list_emb P ys vs"
assms
(induction xs arbitrary: ys zs)
case Nil then show ?case by auto
case (Cons x xs)
then obtain us v vs where
zs: "zs = us @ v # vs" and p: "P x v" and lh: "list_emb P (xs @ ys) vs"
by (auto dest: list_emb_ConsD)
obtain sk0 :: "'a list ==> 'a list ==> 'a list" and sk1 :: "'a list ==> 'a list ==> 'a list" where
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "macro" is null
using Cons(1) by (metis (no_types))
hence "∀x2. list_emb P (x # xs) (x2 @ v # sk0 ys vs)" using p lh by auto
thus ?case using lh zs sk by (metis (no_types) append_Cons append_assoc)
list_emb_strict_suffix:
assumes "list_emb P xs ys" and "strict_suffix ys zs"
shows "list_emb P xs zs"
using assms(2) and list_emb_append2 [OF assms(1)] by (auto simp: strict_suffix_def suffix_def)
list_emb_suffix:
assumes "list_emb P xs ys" and "suffix ys zs"
shows "list_emb P xs zs"
assms and list_emb_strict_suffix
strict_suffix_reflclp_conv[symmetric] by auto
list_emb_length: "list_emb P xs ys ==> length xs ≤ length ys"
by (induct rule: list_emb.induct) auto
list_emb_trans:
assumes "∧x y z. [x ∈ set xs; y ∈ set ys; z ∈ set zs; P x y; P y z]==> P x z"
shows "[list_emb P xs ys; list_emb P ys zs]==> list_emb P xs zs"
-
assume "list_emb P xs ys" and "list_emb P ys zs"
then show "list_emb P xs zs" using assms
proof (induction arbitrary: zs)
case list_emb_Nil show ?case by blast
next
case (list_emb_Cons xs ys y)
from list_emb_ConsD [OF ‹list_emb P (y#ys) zs›] obtain us v vs
where zs: "zs = us @ v # vs" and "P== y v" and "list_emb P ys vs" by blast
then have "list_emb P ys (v#vs)" by blast
then have "list_emb P ys zs" unfolding zs by (rule list_emb_append2)
from list_emb_Cons.IH [OF this] and list_emb_Cons.prems show ?case by auto
next
case (list_emb_Cons2 x y xs ys)
from list_emb_ConsD [OF ‹] obtain us v vs
where zs: "zs = us @ v # vs" and "P y v" and "list_emb P ys vs" by blast
with list_emb_Cons2 have "list_emb P xs vs" by auto
moreover have "P x v"
proof -
from zs have "v ∈ set zs" by auto
moreover have "x ∈ set (x#xs)" and "y ∈ set (y#ys)" by simp_all
ultimately show ?thesis
using ‹P x y› and ‹P y v› and list_emb_Cons2
by blast
qed
ultimately have "list_emb P (x#xs) (v#vs)" by blast
then show ?case unfolding zs by (rule list_emb_append2)
qed
list_emb_set:
assumes "list_emb P xs ys" and "x ∈ set xs"
obtains y where "y ∈ set ys" and "P x y"
using assms by (induct) auto
list_emb_Cons_iff1 [simp]:
assumes "P x y"
shows "list_emb P (x#xs) (y#ys) ⟷ list_emb P xs ys"
using assms by (subst list_emb.simps) (auto dest: list_emb_ConsD)
list_emb_Cons_iff2 [simp]:
assumes "¬P x y"
shows "list_emb P (x#xs) (y#ys) ⟷ list_emb P (x#xs) ys"
using assms by (subst list_emb.simps) auto
list_emb_code [code]:
"list_emb P [] ys ⟷ True"
"list_emb P (x#xs) [] ⟷ False"
"list_emb P (x#xs) (y#ys) ⟷ (if P x y then list_emb P xs ys else list_emb P (x#xs) ys)"
by simp_all
‹Subsequences (special case of homeomorphic embedding)›
subseq :: "'a list ==> 'a list ==> bool"
where "subseq xs ys ≡ list_emb (=) xs ys"
show ‹subseq xs xs› for xs :: ‹'a list›
using refl by (rule list_emb_refl)
show ‹subseq xs zs› if ‹subseq xs ys› and ‹subseq ys zs›
for xs ys zs :: ‹'a list›
using trans [OF refl] that by (rule list_emb_trans) simp
show ‹xs = ys› if ‹subseq xs ys› and ‹subseq ys xs›
for xs ys :: ‹'a list›
using that proof induction
case list_emb_Nil
from list_emb_Nil2 [OF this] show ?case by simp
next
case list_emb_Cons2
then show ?case by simp
next
case list_emb_Cons
hence False using subseq_Cons' by fastforce
then show ?case ..
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "macro" is null
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "brackoff" is null
for xs ys :: ‹'a list›
by (auto simp: strict_subseq_def)
subseq_order: order subseq strict_subseq
by (rule ordering_orderI) standard
‹a subsequence of a sorted list›
sorted_subset_imp_subseq:
fixes xs :: "'a::order list"
assumes "set xs ⊆ set ys" "sorted_wrt (<)
shows "subseq xs ys"
using assms
(induction xs arbitrary: ys)
case Nil
then show ?case
by auto
case (Cons x xs)
then have "x ∈ set ys"
by auto
then obtain us vs where 🍋: "ys = us @ [x] @ vs"
by (metis append.left_neutral append_eq_Cons_conv split_list)
moreover
have "set xs ⊆ set vs"
using Cons.prems by (fastforce simp: 🍋 sorted_wrt_append)
with Cons have "subseq xs vs"
by (metis 🍋 sorted_wrt.simps(2) sorted_wrt_append)
ultimately show ?case
by auto
have "xs' = xs @ zs ∧ ys' = ys @ zs ⟶ subseq xs ys"
if"subseq xxs' ys'" for xs' ys' xs ys zs :: "'a list"
using that
proof (induct arbitrary: xs ys zs)
case list_emb_Nil
show ?case by simp
next
case (list_emb_Cons xs' ys' x)
have ?case if "ys = []"
using list_emb_Cons(1) that by auto
moreover
have ?case if "ys = x#us" for us
using list_emb_Cons(2) that by (simp add: list_emb.list_emb_Cons)
ultimately show ?case
by (auto simp: Cons_eq_append_conv)
next
case (list_emb_Cons2 x y xs' ys')
have ?case if "xs = []"
using list_emb_Cons2(1) that by auto
moreover
have ?case if "xs = x#us" "ys = x#vs" for us vs
using list_emb_Cons2 that by auto
moreover
have ?case if "xs = x#us" "ys = []" for us
using list_emb_Cons2(2) that by bestsimp
ultimately show ?case
using ‹x = y› by (auto simp: Cons_eq_append_conv)
qed
then show "?l ==> ?r" by blast
show "?r ==> ?l" by (metis list_emb_append_mono subseq_order.order_refl)
assume ?lhs thus ?rhs
proof (induction xs "ys @ zs" arbitrary: ys zs rule: list_emb.induct)
case (list_emb_Cons xs ws y ys zs)
from list_emb_Cons(2)[of "tl ys" zs] and list_emb_Cons(2)[of "[]" "tl zs"] and list_emb_Cons(1,3)
show ?case by (cases ys) auto
case (list_emb_Cons2 x y xs ws ys zs)
from list_emb_Cons2(3)[of "tl ys" zs] and list_emb_Cons2(3)[of "[]" "tl zs"]
and list_emb_Cons2(1,2,4)
show ?case by (cases ys) (auto simp: Cons_eq_append_conv)
qed auto
(auto intro: list_emb_append_mono)
subseq_appendE [case_names append]:
assumes "subseq xs (ys @ zs)"
obtains xs1 xs2 where "xs = xs1 @ xs2" "subseq xs1 ys" "subseq xs2 zs"
using assms by (subst (asm) subseq_append_iff) auto
subseq_drop_many: "subseq xs ys ==> subseq xs (zs @ ys)"
by (induct zs) auto
show ?R if ?L using ttha
proof (induct)
case list_emb_Nil
show ?case by (metis nths_empty)
next
case (list_emb_Cons xs ys x)
then obtain N where "xs = nths ys N" by blast
then have "xs = nths (x#ys) (Suc ` N)"
by (clarsimp simp add: nths_Cons inj_image_mem_iff)
then show ?case by blast
next
case (list_emb_Cons2 x y xs ys)
then obtain N where "xs = nths ys N" by blast
then have "x#xs = nths (x#ys) (insert 0 (Suc ` N))"
by (clarsimp simp add: nths_Cons inj_image_mem_iff)
moreover from list_emb_Cons2 have "x = y" by simp
ultimately show ?case by blast
qed
show ?L if ?R
proof -
from that obtain N where "xs = nths ys N" ..
moreover have "subseq (nths ys N) ys"
proof (induct ys arbitrary: N)
case Nil
show ?case by simp
next
case Cons
then show ?case by (auto simp: nths_Cons)
qed
ultimately show ?thesis by simp
qed
‹Contiguous sublists›
‹‹sublist››
sublist :: "'a list ==> 'a list ==> bool" where
"sublist xs ys = (∃ps ss. ys = ps @ xs @ ss)"
strict_sublist :: "'a list ==> 'a list ==> bool" where
"strict_sublist xs ys ⟷ sublist xs ys ∧ xs ≠ ys"
map_mono_sublist:
assumes "sublist xs ys"
shows "sublist (map f xs) (map f ys)"
-
from assms obtain xs1 xs2 where ys: "ys = xs1 @ xs @ xs2"
by (auto simp: sublist_def)
have "map f ys = map f xs1 @ map f xs @ map f xs2"
by (auto simp: ys)
thus ?thesis
by (auto simp: sublist_def)
assume "sublist (rev xs) (rev ys)"
then obtain as bs where "rev ys = as @ rev xs @ bs"
by (auto simp: sublist_def)
also have "rev … = rev bs @ xs @ rev as" by simp
finally show "sublist xs ys" by simp
assume "sublist xs ys"
then obtain as bs where "ys = as @ xs @ bs"
by (auto simp: sublist_def)
also have "rev … = rev bs @ rev xs @ rev as" by simp
finally show "sublist (rev xs) (rev ys)" by simp
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.