Dear all,
in preparation for the next release I refactored one of our AFP entries
(Abstract-Rewriting). There was an underlying theory Util.thy (quite
big), which essentially turned out to be unused in the rest of the AFP
entry ;) (but we heavily rely on it in IsaFoR, which is not in the AFP).
While refactoring I saw that some lemmas from Util.thy have found their
way (either by moving or independently) into the main Isabelle
distribution (mostly List.thy) -- but without being removed from the AFP
entry.
Still there are many definitions and lemmas left that are not part of
the main distribution (some of which are ugly and ad hoc, but others
quite useful and maybe deserving to end up in the distribution or library).
After this rather long story ;) my actual question: Is there some way to
propose definitions/lemmas for the main distribution/library? If not,
maybe someone of the developers feels like reading through the attached
theory-file and picking out whatever he/she likes?
cheers
chris
On 02/28/2012 10:21 PM, Makarius wrote:
Dear all,
4 months after Isabelle2011-1 we are roughly in the middle between two
official releases. This is a good point to recollect things for the
coming release, better than a few weeks before actual rollout (which
will the time for testing the integrated system, not adding new features).
After 3.4 weeks vacation in Marokko in Jan/Feb and 2 weeks working
through my mail folders like crazy, I still have issues in the pipeline
that need to be reanimated. I also need to figure out which essential
things of the Prover IDE can make it into the release ...
Makarius
_______________________________________________
isabelle-dev mailing list
isabelle-...@in.tum.de
https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
theory Collect
imports
Main
"~~/src/HOL/Library/Infinite_Set"
begin
section {* Auxiliary Lemmas *}
lemma set_not_empty: "xs \<noteq> [] \<longleftrightarrow> set xs \<noteq> {}"
by simp
lemma set_subset_insertI: "set xs \<subseteq> set (List.insert x xs)" by auto
lemma set_removeAll_subset: "set (removeAll x xs) \<subseteq> set xs" by auto
lemma ballI2[Pure.intro]:
assumes "\<And>x y. (x, y) \<in> A \<Longrightarrow> P x y"
shows "\<forall>(x, y)\<in>A. P x y"
using assms by auto
lemma all_Suc_conv[simp]:
"(\<forall>i<Suc n. P i) \<longleftrightarrow> P 0 \<and> (\<forall>i<n. P
(Suc i))" (is "?l = ?r")
proof
assume ?l thus ?r by auto
next
assume ?r show ?l
proof (intro allI impI)
fix i
assume "i < Suc n"
with `?r` show "P i" by (cases i, auto)
qed
qed
lemma ex_Suc_conv[simp]:
"(\<exists>i<Suc n. P i) \<longleftrightarrow> P 0 \<or> (\<exists>i<n. P
(Suc i))" (is "?l = ?r")
using all_Suc_conv[of n "\<lambda>i. \<not> P i"] by blast
subsection {* Induction Rules *}
text {* Induction over a finite set of natural numbers. *}
lemma bound_nat_induct[consumes 1]:
assumes "n \<in> {l..u}" and "P l" and "\<And>n. \<lbrakk>P n; n \<in>
{l..<u}\<rbrakk> \<Longrightarrow> P (Suc n)"
shows "P n"
using assms
proof (induct n)
case (Suc n) thus ?case by (cases "Suc n = l") auto
qed simp
subsection {* Functions on Lists *}
primrec find :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a
option" where
"find _ [] = None"
| "find P (x#xs) = (if P x then Some x else find P xs)"
lemma find_NoneE:
assumes "find P xs = None" shows "\<not> (\<exists>x. x \<in> set xs \<and> P
x)"
using assms
proof (induct xs)
case (Cons x xs)
hence "\<not> (P x)" by auto
with Cons show ?case by auto
qed simp
lemma find_NoneI:
assumes "\<not> (\<exists>x. x \<in> set xs \<and> P x)" shows "find P xs =
None"
using assms
proof (induct xs)
case (Cons x xs)
assume "\<not> (\<exists>y. y \<in> set (x#xs) \<and> P y)"
hence "\<not> (P x)" by auto
with Cons show ?case by auto
qed simp
lemma not_mem_find_None_conv: "\<not> (\<exists>x. x \<in> set xs \<and> P x)
\<longleftrightarrow> find P xs = None"
using find_NoneI find_NoneE by blast
lemma find_SomeD:
assumes "find P xs = Some x"
shows "\<exists>i<length xs. P (xs ! i) \<and> x = (xs ! i) \<and>
(\<forall>j<i. \<not> P (xs ! j))"
using assms
proof (induct xs)
case (Cons y ys)
show ?case
proof (cases "P y")
case True with Cons show ?thesis by auto
next
case False with Cons have "find P ys = Some x" by simp
with Cons have "\<exists>i<length ys. P (ys ! i) \<and> x = ys ! i \<and>
(\<forall>j<i. \<not> P (ys ! j))" by simp
then obtain i where "i < length ys" and "P (ys ! i)" and "x = ys ! i"
and "\<forall>j<i. \<not> P (ys ! j)" by auto
from `i < length ys` have "Suc i < length (y#ys)" by simp
moreover from `P (ys ! i)` have "P ((y#ys) ! Suc i)" by simp
moreover from `x = ys ! i` have "x = (y#ys) ! Suc i" by simp
moreover have "\<forall>j<Suc i. \<not> P ((y#ys) ! j)"
proof (intro allI impI)
fix j assume "j < Suc i" thus "\<not> P ((y#ys) ! j)" using
`\<forall>j<i. \<not> P (ys ! j)` False
by (induct j) auto
qed
ultimately show ?thesis by best
qed
qed simp
lemma find_SomeI:
assumes "\<exists>i<length xs. P (xs ! i) \<and> x = (xs ! i) \<and>
(\<forall>j<i. \<not> P (xs ! j))"
shows "find P xs = Some x"
using assms
proof (induct xs)
case (Cons y ys)
with `\<exists>i<length (y#ys). P ((y#ys) ! i) \<and> x = (y#ys) ! i \<and>
(\<forall>j<i. \<not> P ((y#ys) ! j))`
obtain i where "i < length (y#ys)" and "P ((y#ys) ! i)"
and "x = (y#ys) ! i" and "\<forall>j<i. \<not> P ((y#ys) ! j)" by force
show ?case
proof (cases i)
case 0
with `P ((y#ys) ! i)` have "P y" by simp
with `x = (y#ys) ! i` 0 have "y = x" by simp
with `P y` show ?thesis by simp
next
case (Suc k)
from Suc `\<forall>j<i. \<not> P ((y#ys) ! j)` have "\<not> P y" by auto
hence rec: "find P (y#ys) = find P ys" by simp
from Suc `i < length (y#ys)` have k1: "k < length ys" by simp
from Suc `P ((y#ys) ! i)` have k2: "P (ys ! k)" by simp
from Suc `x = (y#ys) ! i` have k3:"x = (ys ! k)" by simp
from Suc `\<forall>j<i. \<not> P ((y#ys) ! j)` have "\<forall>j<k. \<not> P
(ys ! j)" by auto
with k1 k2 k3 have "\<exists>i<length ys. P (ys ! i) \<and> x = ys ! i
\<and> (\<forall>j<i. \<not> P (ys ! j))" by auto
with Cons have "find P ys = Some x" by auto
with rec show ?thesis by simp
qed
qed simp
lemma ex_find_Some_conv:
"(\<exists>i<length xs. P (xs ! i) \<and> x = xs ! i \<and> (\<forall>j<i.
\<not> P (xs ! j))) \<longleftrightarrow> find P xs = Some x"
by (blast intro: find_SomeI dest: find_SomeD)
lemma find_cong[fundef_cong]:
assumes xs: "xs = ys" and set: "\<And>x. x \<in> set ys \<Longrightarrow> f x
= g x"
shows "find f xs = find g ys"
proof (cases "find f xs")
case None
hence "find f ys = None" using xs by simp
hence "\<not>(\<exists> x. x \<in> set ys \<and> f x)" using find_NoneE by
auto
hence "\<not>(\<exists> x. x \<in> set ys \<and> g x)" using set by best
hence "find g ys = None" using find_NoneI by auto
thus ?thesis using None by auto
next
case (Some x)
hence "find f ys = Some x" using xs by simp
hence "\<exists>i<length ys. f(ys!i) \<and> (x = (ys!i)) \<and>
(\<forall>j<i. \<not> f (ys!j))" by (rule find_SomeD)
hence "\<exists>i<length ys. g(ys!i) \<and> (x = (ys!i)) \<and>
(\<forall>j<i. \<not> g (ys!j))" using set by auto
hence "find g ys = Some x" by (rule find_SomeI)
thus ?thesis using Some by auto
qed
primrec
list_union :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list"
where
"list_union [] ys = ys"
| "list_union (x # xs) ys = (let zs = list_union xs ys in if x \<in> set zs
then zs else x # zs)"
lemma set_list_union[simp]: "set (list_union xs ys) = set xs \<union> set ys"
proof (induct xs)
case (Cons x xs) thus ?case by (cases "x \<in> set (list_union xs ys)") (auto)
qed simp
declare list_union.simps[simp del]
(*Why was list_inter thrown out of List.thy?*)
fun list_inter :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
"list_inter [] bs = []"
| "list_inter (a#as) bs =
(if a \<in> set bs then a # list_inter as bs else list_inter as bs)"
lemma set_list_inter[simp]:
"set (list_inter xs ys) = set xs \<inter> set ys"
by (induct rule: list_inter.induct) simp_all
declare list_inter.simps[simp del]
primrec list_diff :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
"list_diff [] ys = []"
| "list_diff (x # xs) ys = (let zs = list_diff xs ys in if x \<in> set ys then
zs else x # zs)"
lemma set_list_diff[simp]:
"set (list_diff xs ys) = set xs - set ys"
proof (induct xs)
case (Cons x xs) thus ?case by (cases "x \<in> set ys") (auto)
qed simp
declare list_diff.simps[simp del]
fun lookup :: "'a \<Rightarrow> ('a \<times> 'b) list \<Rightarrow> 'b option"
where
"lookup x [] = None"
| "lookup x ((y, v)#xs) = (if x = y then Some v else lookup x xs)"
lemma lookup_NoneD:
assumes "lookup x xs = None"
shows "\<not> (\<exists>v. (x, v) \<in> set xs)"
using assms
proof (induct xs)
case (Cons yv xs)
show ?case
proof (cases yv)
case (Pair y v)
with Cons show ?thesis by (cases "x = y") auto
qed
qed simp
lemma lookup_SomeD:
assumes "lookup x xs = Some v"
shows "(x, v) \<in> set xs"
using assms
proof (induct xs)
case (Cons yv xs)
show ?case
proof (cases yv)
case (Pair y v)
with Cons show ?thesis by (cases "x = y") auto
qed
qed simp
subsection {* Lists and Sets *}
lemma nth_append_take:
assumes "i \<le> length xs" shows "(take i xs @ y#ys)!i = y"
proof -
from assms have a: "length(take i xs) = i" by simp
have "(take i xs @ y#ys)!(length(take i xs)) = y" by (rule nth_append_length)
thus ?thesis unfolding a .
qed
lemma nth_append_take_is_nth_conv:
assumes "i < j" and "j \<le> length xs" shows "(take j xs @ ys)!i = xs!i"
proof -
from assms have "i < length(take j xs)" by simp
hence "(take j xs @ ys)!i = take j xs ! i" unfolding nth_append by simp
thus ?thesis unfolding nth_take[OF assms(1)] .
qed
lemma nth_append_drop_is_nth_conv:
assumes "j < i" and "j \<le> length xs" and "i \<le> length xs"
shows "(take j xs @ y # drop (Suc j) xs)!i = xs!i"
proof -
from assms have j: "length(take j xs) = j" by auto
from `j < i` obtain n where "Suc(j + n) = i" using less_imp_Suc_add by auto
with assms have i: "i = length(take j xs) + Suc n" by auto
have len: "Suc j + n \<le> length xs" using assms i by auto
have "(take j xs @ y # drop (Suc j) xs)!i =
(y # drop (Suc j) xs)!(i - length(take j xs))" unfolding nth_append i by
auto
also have "\<dots> = (y # drop (Suc j) xs)!(Suc n)" unfolding i by simp
also have "\<dots> = (drop (Suc j) xs)!n" by simp
finally show ?thesis unfolding nth_drop[OF len] using i j by simp
qed
lemma nth_append_take_drop_is_nth_conv:
assumes "i \<le> length xs" and "j \<le> length xs" and "i \<noteq> j"
shows "(take j xs @ y # drop (Suc j) xs)!i = xs!i"
proof -
from assms have "i < j \<or> i > j" by auto
thus ?thesis
proof
assume "i < j" thus ?thesis using assms by (auto simp:
nth_append_take_is_nth_conv)
next
assume "j < i" thus ?thesis using assms by (auto simp:
nth_append_drop_is_nth_conv)
qed
qed
lemma take_drop_imp_nth: "\<lbrakk>take i ss @ x # drop (Suc i) ss =
ss\<rbrakk> \<Longrightarrow> x = ss!i"
proof (induct ss arbitrary: i)
case Nil thus ?case by auto
next
case (Cons s ss)
from `take i (s#ss) @ x # drop (Suc i) (s#ss) = (s#ss)` show ?case
proof (induct i)
case 0 thus ?case by auto
next
case (Suc i)
from Cons have IH: "take i ss @ x # drop (Suc i) ss = ss \<Longrightarrow> x
= ss!i" by auto
from Suc have "take i ss @ x # drop (Suc i) ss = ss" by auto
with IH show ?case by auto
qed
qed
lemma nth_take_prefix:
"length ys \<le> length xs \<Longrightarrow> \<forall>i < length ys. xs!i =
ys!i \<Longrightarrow> take (length ys) xs = ys"
proof (induct ys arbitrary: xs)
case Nil thus ?case by auto
next
case (Cons y ys) note IH = this
show ?case
proof (cases xs)
case Nil thus ?thesis using Cons by simp
next
case (Cons z zs)
hence "xs!0 = z" by simp
with IH have "z = y" by auto
from IH have "\<forall>i < length ys. xs!(Suc i) = ys!i" by auto
hence A:"\<forall>i < length ys. zs!i = ys!i" using Cons by auto
have B:"length ys \<le> length zs" using IH Cons by auto
have C:"take (length ys) zs = ys" using IH A B by simp
have "take (length (y#ys)) (z#zs) = z#(take (length ys) zs)" by simp
also have "\<dots> = z#ys" using C by simp
finally show ?thesis unfolding `z = y` `xs = z#zs` .
qed
qed
lemma nth_drop_0: "0 < length ss \<Longrightarrow> (ss!0)#drop (Suc 0) ss = ss"
by (induct ss) auto
lemma map_nth_Suc: "map f [0 ..< Suc n] = f 0 # map (\<lambda> i. f (Suc i)) [0
..< n]"
by (induct n arbitrary: f, auto)
lemma zip_nth_conv: "length xs = length ys \<Longrightarrow> zip xs ys = map
(\<lambda> i. (xs ! i, ys ! i)) [0 ..< length ys]"
proof (induct xs arbitrary: ys, simp)
case (Cons x xs)
then obtain y yys where ys: "ys = y # yys" by (cases ys, auto)
with Cons have len: "length xs = length yys" by simp
show ?case unfolding ys
by (simp del: upt_Suc add: map_nth_Suc, unfold Cons(1)[OF len], simp)
qed
lemma append_Cons_nth_left:
assumes "i < length xs"
shows "(xs @ u # ys) ! i = xs ! i"
using assms nth_append[of xs _ i] by simp
lemma append_Cons_nth_middle:
assumes "i = length xs"
shows "(xs @ y # zs) ! i = y"
using assms by auto
lemma append_Cons_nth_right:
assumes "i > length xs"
shows "(xs @ u # ys) ! i = (xs @ z # ys) ! i"
proof -
from assms have "i - length xs > 0" by auto
then obtain j where j: "i - length xs = Suc j" by (cases "i - length xs",
auto)
thus ?thesis by (simp add: nth_append)
qed
lemma append_Cons_nth_not_middle:
assumes "i \<noteq> length xs"
shows "(xs @ u # ys) ! i = (xs @ z # ys) ! i"
proof (cases "i < length xs")
case True
thus ?thesis by (simp add: append_Cons_nth_left)
next
case False
with assms have "i > length xs" by arith
thus ?thesis by (rule append_Cons_nth_right)
qed
lemmas append_Cons_nth = append_Cons_nth_middle append_Cons_nth_not_middle
lemma map_id[simp]: "map id xs = xs" by (induct xs) auto
lemma map_nth_conv: "map f ss = map g ts \<Longrightarrow> \<forall>i < length
ss. f(ss!i) = g(ts!i)"
proof (intro allI impI)
fix i show "map f ss = map g ts \<Longrightarrow> i < length ss
\<Longrightarrow> f(ss!i) = g(ts!i)"
proof (induct ss arbitrary: i ts)
case Nil thus ?case by (induct ts) auto
next
case (Cons s ss) thus ?case
proof (induct ts)
case Nil thus ?case by simp
next
case (Cons t ts) thus ?case by (cases i) auto
qed
qed
qed
lemma replicate_prop:
assumes "P x"
shows "\<forall>y\<in>set (replicate n x). P y"
using assms by (induct n) simp_all
lemma set_foldr_remdups_set_map_conv[simp]:
"set (foldr (\<lambda>x xs. remdups (f x @ xs)) xs []) = \<Union>set (map
(set \<circ> f) xs)"
by (induct xs) auto
lemma nth_map_conv:
assumes "length xs = length ys"
and "\<forall>i<length xs. f (xs ! i) = g (ys ! i)"
shows "map f xs = map g ys"
using assms
proof (induct xs arbitrary: ys)
case (Cons x xs) thus ?case
proof (induct ys)
case (Cons y ys)
have "\<forall>i<length xs. f (xs ! i) = g (ys ! i)"
proof (intro allI impI)
fix i assume "i < length xs" thus "f (xs ! i) = g (ys ! i)" using Cons(4)
by force
qed
with Cons show ?case by auto
qed simp
qed simp
lemma map_nth_eq_conv:
assumes len: "length xs = length ys"
shows "(map f xs = ys) = (\<forall>i<length ys. f (xs ! i) = ys ! i)" (is "?l
= ?r")
proof -
have "(map f xs = ys) = (map f xs = map id ys)" by auto
also have "... = (\<forall> i < length ys. f (xs ! i) = id (ys ! i))" using
map_nth_conv[of f xs id ys] nth_map_conv[OF len, of f id] unfolding len
by blast
finally show ?thesis by auto
qed
lemma eq_length_concat_nth:
assumes "length xs = length ys"
and "\<And>i. i < length xs \<Longrightarrow> length (xs ! i) = length (ys
! i)"
shows "length (concat xs) = length (concat ys)"
using assms
proof (induct xs arbitrary: ys)
case Nil
thus ?case by auto
next
case (Cons x xs zs)
from Cons(2) obtain y ys where zs: "zs = y # ys" by (cases zs, auto)
note Cons = Cons[unfolded zs]
from Cons(2) have len: "length xs = length ys" by simp
from Cons(3)[of 0] have xy: "length x = length y" by simp
{
fix i
assume "i < length xs"
with Cons(3)[of "Suc i"]
have "length (xs ! i) = length (ys ! i)" by simp
}
from Cons(1)[OF len this] have ind: "length (concat xs) = length (concat ys)"
by simp
show ?case unfolding zs using xy ind by auto
qed
lemma concat_all_nth:
assumes "length xs = length ys"
and "\<And>i. i < length xs \<Longrightarrow> length (xs ! i) = length (ys
! i)"
and "\<And>i j. i < length xs \<Longrightarrow> j < length (xs ! i)
\<Longrightarrow> P (xs ! i ! j) (ys ! i ! j)"
shows "\<forall>k<length (concat xs). P (concat xs ! k) (concat ys ! k)"
using assms
proof (induct xs arbitrary: ys)
case Nil
thus ?case by auto
next
case (Cons x xs zs)
from Cons(2) obtain y ys where zs: "zs = y # ys" by (cases zs, auto)
note Cons = Cons[unfolded zs]
from Cons(2) have len: "length xs = length ys" by simp
from Cons(3)[of 0] have xy: "length x = length y" by simp
from Cons(4)[of 0] xy have pxy: "\<And> j. j < length x \<Longrightarrow> P
(x ! j) (y ! j)" by auto
{
fix i
assume i: "i < length xs"
with Cons(3)[of "Suc i"]
have len: "length (xs ! i) = length (ys ! i)" by simp
from Cons(4)[of "Suc i"] i len have "\<And> j. j < length (xs ! i)
\<Longrightarrow> P (xs ! i ! j) (ys ! i ! j)"
by auto
note len and this
}
from Cons(1)[OF len this] have ind: "\<And> k. k < length (concat xs)
\<Longrightarrow> P (concat xs ! k) (concat ys ! k)"
by auto
show ?case unfolding zs concat.simps
proof (intro allI impI)
fix k
assume k: "k < length (x @ concat xs)"
show "P ((x @ concat xs) ! k) ((y @ concat ys) ! k)"
proof (cases "k < length x")
case True
show ?thesis unfolding nth_append using True xy pxy[OF True]
by simp
next
case False
with k have "k - (length x) < length (concat xs)" by auto
then obtain n where n: "k - length x = n" and nxs: "n < length (concat
xs)" by auto
show ?thesis unfolding nth_append n n[unfolded xy] using False xy ind[OF
nxs]
by auto
qed
qed
qed
lemma [code_unfold]: "set xs \<subseteq> set ys \<longleftrightarrow> list_all
(\<lambda>x. x \<in> set ys) xs"
unfolding list_all_iff by auto
fun concat_lists :: "'a list list \<Rightarrow> 'a list list" where
"concat_lists [] = [[]]"
| "concat_lists (as # xs) = (let rec = concat_lists xs in concat (map
(\<lambda>vec. map (\<lambda>a. a # vec) as) rec))"
lemma set_concat_lists[simp]:
shows "set (concat_lists xs) = {as. length as = length xs \<and>
(\<forall>i<length xs. as ! i \<in> set (xs ! i))}"
proof (induct xs)
case Nil
show ?case by auto
next
case (Cons as xs)
have id: "set (concat_lists (as # xs)) =
{(a # bs) | a bs. length (a # bs) = length (as # xs) \<and> (\<forall>i<Suc
(length xs). (a # bs) ! i \<in> set ((as # xs) ! i))}" (is "?L = ?M")
by (auto simp: Cons)
show ?case (is "_ = ?R")
proof -
have one: "?M \<subseteq> ?R" by auto
{
fix cs
assume cs: "cs \<in> ?R"
then obtain c bs where cbs: "cs = c # bs" by (cases cs, auto)
from cs have "cs \<in> ?M" unfolding cbs by auto
}
with one show ?thesis unfolding id by auto
qed
qed
declare concat_lists.simps[simp del]
fun max_list :: "nat list \<Rightarrow> nat" where
"max_list [] = 0"
| "max_list (x # xs) = max x (max_list xs)"
lemma max_list: "x \<in> set xs \<Longrightarrow> x \<le> max_list xs"
by (induct xs) auto
fun max_f :: "(nat \<Rightarrow> nat) \<Rightarrow> nat \<Rightarrow> nat" where
"max_f f 0 = 0"
| "max_f f (Suc i) = max (f i) (max_f f i)"
lemma max_f: "i < n \<Longrightarrow> f i \<le> max_f f n"
proof (induct n)
case (Suc n)
thus ?case by (cases "i = n", auto)
qed simp
lemma max_list_mem: "xs \<noteq> [] \<Longrightarrow> max_list xs \<in> set xs"
proof (induct xs)
case (Cons x xs)
show ?case
proof (cases "x \<ge> max_list xs")
case True
thus ?thesis by auto
next
case False
hence max: "max_list xs > x" by auto
hence nil: "xs \<noteq> []" by (cases xs, auto)
from max have max: "max x (max_list xs) = max_list xs" by auto
from Cons(1)[OF nil] max show ?thesis by auto
qed
qed simp
lemma max_list_set: "max_list xs = (if set xs = {} then 0 else (THE x. x \<in>
set xs \<and> (\<forall> y \<in> set xs. y \<le> x)))"
proof (cases "xs = []")
case True thus ?thesis by simp
next
case False
note p = max_list_mem[OF this] max_list[of _ xs]
from False have id: "(set xs = {}) = False" by simp
show ?thesis unfolding id if_False
proof (rule the_equality[symmetric], intro conjI ballI, rule p, rule p)
fix x
assume "x \<in> set xs \<and> (\<forall> y \<in> set xs. y \<le> x)"
hence mem: "x \<in> set xs" and le: "\<And> y. y \<in> set xs
\<Longrightarrow> y \<le> x" by auto
from max_list[OF mem] le[OF max_list_mem[OF False]]
show "x = max_list xs" by simp
qed
qed
lemma max_list_eq_set: "set xs = set ys \<Longrightarrow> max_list xs =
max_list ys"
unfolding max_list_set by simp
fun min_list :: "('a :: linorder) list \<Rightarrow> 'a" where
"min_list [x] = x"
| "min_list (x # xs) = min x (min_list xs)"
lemma min_list: "(x :: 'a :: linorder) \<in> set xs \<Longrightarrow> min_list
xs \<le> x"
proof (induct xs, simp)
case (Cons y ys) note oCons = this
show ?case
proof (cases ys)
case Nil
thus ?thesis using Cons by auto
next
case (Cons z zs)
hence id: "min_list (y # ys) = min y (min_list ys)"
by auto
show ?thesis
proof (cases "x = y")
case True
show ?thesis unfolding id True by auto
next
case False
have "min y (min_list ys) \<le> min_list ys" by auto
also have "... \<le> x" using oCons False by auto
finally show ?thesis unfolding id .
qed
qed
qed
lemma min_list_Cons:
assumes xy: "x \<le> y"
and len: "length xs = length ys"
and xsys: "min_list xs \<le> min_list ys"
shows "min_list (x # xs) \<le> min_list (y # ys)"
proof (cases xs)
case Nil
with len have ys: "ys = []" by simp
with xy Nil show ?thesis by simp
next
case (Cons x' xs')
with len obtain y' ys' where ys: "ys = y' # ys'" by (cases ys, auto)
from Cons have one: "min_list (x # xs) = min x (min_list xs)" by auto
from ys have two: "min_list (y # ys) = min y (min_list ys)" by auto
show ?thesis unfolding one two using xy xsys
unfolding min_def by auto
qed
lemma min_list_nth:
assumes "length xs = length ys"
and "\<And>i. i < length ys \<Longrightarrow> xs ! i \<le> ys ! i"
shows "min_list xs \<le> min_list ys"
using assms
proof (induct xs arbitrary: ys)
case Nil
thus ?case by auto
next
case (Cons x xs zs)
from Cons(2) obtain y ys where zs: "zs = y # ys" by (cases zs, auto)
note Cons = Cons[unfolded zs]
from Cons(2) have len: "length xs = length ys" by simp
from Cons(3)[of 0] have xy: "x \<le> y" by simp
{
fix i
assume "i < length xs"
with Cons(3)[of "Suc i"] Cons(2)
have "xs ! i \<le> ys ! i" by simp
}
from Cons(1)[OF len this] Cons(2) have ind: "min_list xs \<le> min_list ys"
by simp
show ?case unfolding zs
by (rule min_list_Cons[OF xy len ind])
qed
lemma min_list_ex:
assumes "xs \<noteq> []" shows "\<exists>x\<in>set xs. min_list xs = x"
using assms
proof (induct xs)
case Nil thus ?case by simp
next
case (Cons x xs) note oCons = this
show ?case
proof (cases xs)
case Nil
thus ?thesis by auto
next
case (Cons y ys)
hence id: "min_list (x # xs) = min x (min_list xs)" and nNil: "xs \<noteq>
[]" by auto
show ?thesis
proof (cases "x \<le> min_list xs")
case True
show ?thesis unfolding id
by (rule bexI[of _ x], insert True, auto simp: min_def)
next
case False
show ?thesis unfolding id min_def
using oCons(1)[OF nNil] False by auto
qed
qed
qed
lemma min_list_subset:
assumes subset: "set ys \<subseteq> set xs" and mem: "min_list xs \<in> set
ys"
shows "min_list xs = min_list ys"
proof -
from subset mem have "xs \<noteq> []" by auto
from min_list_ex[OF this] obtain x where x: "x \<in> set xs" and mx:
"min_list xs = x" by auto
from min_list[OF mem] have two: "min_list ys \<le> min_list xs" by auto
from mem have "ys \<noteq> []" by auto
from min_list_ex[OF this] obtain y where y: "y \<in> set ys" and my:
"min_list ys = y" by auto
from y subset have "y \<in> set xs" by auto
from min_list[OF this] have one: "min_list xs \<le> y" by auto
from one two
show ?thesis unfolding mx my by auto
qed
lemma lookup_None[simp]:
assumes "V \<inter> set vs = {}" and "x \<in> V" shows "lookup x (zip vs ts)
= None"
using assms proof (induct vs arbitrary: ts)
case Nil show ?case by simp
next
case (Cons v vs)
note IH = this
hence neq: "v \<noteq> x" by auto
show ?case
proof (cases ts)
case Nil show ?thesis unfolding Nil by simp
next
case (Cons t ts')
from IH have IH': "lookup x (zip vs ts') = None" by auto
have "lookup x (zip (v#vs) ts) = lookup x ((v,t)#zip vs ts')" unfolding
Cons by simp
also have "\<dots> = lookup x (zip vs ts')" using neq by simp
also have "\<dots> = None" unfolding IH' by simp
finally show ?thesis .
qed
qed
lemma lookup_Some[simp]:
assumes "distinct vs" and "length vs \<le> length ts" and "i < length vs"
shows "lookup (vs!i) (zip vs ts) = Some(ts!i)"
using assms proof (induct i arbitrary: vs ts)
case 0 thus ?case by (induct ts) (induct vs,auto)+
next
case (Suc i) show ?case
proof (cases ts)
case Nil with Suc show ?thesis unfolding Nil by simp
next
case (Cons t ts')
note Cons' = this
show ?thesis
proof (cases vs)
case Nil from Suc show ?thesis unfolding Cons' Nil by simp
next
case (Cons v vs') from Suc show ?thesis unfolding Cons Cons' by auto
qed
qed
qed
lemma lookup_append_Some: "lookup x ps = Some y \<Longrightarrow> lookup x (ps
@ qs) = Some y"
by (induct ps, auto)
lemma lookup_append_None: "lookup x ps = None \<Longrightarrow> lookup x (ps @
qs) = lookup x qs"
by (induct ps, auto)
lemma take_drop_update_first: assumes "j < length ds" and "length cs = length
ds"
shows "(take j ds @ drop j cs)[j := ds ! j] = take (Suc j) ds @ drop (Suc j)
cs"
using assms
proof (induct j arbitrary: ds cs)
case 0
then obtain d dds c ccs where ds: "ds = d # dds" and cs: "cs = c # ccs" by
(cases ds, simp, cases cs, auto)
show ?case unfolding ds cs by auto
next
case (Suc j)
then obtain d dds c ccs where ds: "ds = d # dds" and cs: "cs = c # ccs" by
(cases ds, simp, cases cs, auto)
from Suc(1)[of dds ccs] Suc(2) Suc(3) show ?case unfolding ds cs by auto
qed
lemma take_drop_update_second: assumes "j < length ds" and "length cs = length
ds"
shows "(take j ds @ drop j cs)[j := cs ! j] = take j ds @ drop j cs"
using assms
proof (induct j arbitrary: ds cs)
case 0
then obtain d dds c ccs where ds: "ds = d # dds" and cs: "cs = c # ccs" by
(cases ds, simp, cases cs, auto)
show ?case unfolding ds cs by auto
next
case (Suc j)
then obtain d dds c ccs where ds: "ds = d # dds" and cs: "cs = c # ccs" by
(cases ds, simp, cases cs, auto)
from Suc(1)[of dds ccs] Suc(2) Suc(3) show ?case unfolding ds cs by auto
qed
lemma distinct_take_drop:
assumes dist: "distinct vs" and len: "i < length vs" shows "distinct(take i
vs @ drop (Suc i) vs)" (is "distinct(?xs@?ys)")
proof -
from id_take_nth_drop[OF len] have vs[symmetric]: "vs = ?xs @ vs!i # ?ys" .
with dist have "distinct ?xs" and "distinct(vs!i#?ys)" and "set ?xs \<inter>
set(vs!i#?ys) = {}" using distinct_append[of ?xs "vs!i#?ys"] by auto
hence "distinct ?ys" and "set ?xs \<inter> set ?ys = {}" by auto
with `distinct ?xs` show ?thesis using distinct_append[of ?xs ?ys] vs by simp
qed
primrec option_to_list :: "'a option \<Rightarrow> 'a list" where
"option_to_list (Some a) = [a]"
| "option_to_list None = []"
lemma option_to_list_sound[simp]: "set (option_to_list t) \<equiv> Option.set t"
by (induct t) auto
subsection {* size estimations *}
lemma list_size_pointwise2: assumes "length xs = length ys"
and "\<And> i. i < length ys \<Longrightarrow> f (xs ! i) \<le> g (ys ! i)"
shows "list_size f xs \<le> list_size g ys"
proof -
have id: "(list_size f xs \<le> list_size g ys) = (listsum (map f xs) \<le>
listsum (map g ys))"
unfolding list_size_conv_listsum assms(1) by auto
have "map f xs = map f (map (op ! xs) [0..<length xs])" using map_nth[of xs]
by simp
also have "... = map (\<lambda> i. f (xs ! i)) [0..<length xs]" (is "_ =
?xs") by simp
finally have xs: "map f xs = ?xs" .
have "map g ys = map g (map (op ! ys) [0..<length ys])" using map_nth[of ys]
by simp
also have "... = map (\<lambda> i. g (ys ! i)) [0..<length xs]" (is "_ =
?ys") using assms by simp
finally have ys: "map g ys = ?ys" .
show ?thesis
unfolding id unfolding xs ys
by (rule listsum_mono, insert assms, auto)
qed
lemma size_simp1: "t \<in> set ts \<Longrightarrow> size t < Suc (list_size
size ts)"
by (induct ts) auto
lemma size_simp2: "t \<in> set ts \<Longrightarrow> size t < Suc (Suc(size s +
list_size size ts))"
by (induct ts) auto
lemma size_simp3: assumes mem: "(x,y) \<in> set (zip xs ys)"
shows "size x < Suc (list_size size xs)"
using set_zip_leftD[OF mem] size_simp1 by auto
lemma size_simp4: assumes mem: "(x,y) \<in> set (zip xs ys)"
shows "size y < Suc (list_size size ys)"
using set_zip_rightD[OF mem] using size_simp1 by auto
subsection {* Partitions *}
text {* Check whether a list of sets forms a partition, i.e.,
whether the sets are pairwise disjoint. *}
definition is_partition :: "('a set)list \<Rightarrow> bool"
where "is_partition cs = (\<forall>j<length cs. \<forall>i<j. cs!i \<inter>
cs!j = {})"
(* and an equivalent but more symmetric version *)
definition is_partition_alt :: "('a set)list \<Rightarrow> bool"
where "is_partition_alt cs = (\<forall> i j. i < length cs \<and> j < length cs
\<and> i \<noteq> j \<longrightarrow> cs!i \<inter> cs!j = {})"
lemma is_partition_alt: "is_partition = is_partition_alt"
proof (intro ext)
fix cs
{
assume "is_partition_alt cs"
hence "is_partition cs" unfolding is_partition_def is_partition_alt_def by
auto
}
moreover
{
assume part: "is_partition cs"
have "is_partition_alt cs" unfolding is_partition_alt_def
proof (intro allI impI)
fix i j
assume "i < length cs \<and> j < length cs \<and> i \<noteq> j"
with part show "cs ! i \<inter> cs ! j = {}"
unfolding is_partition_def
by (cases "i < j", simp, cases "j < i", force, simp)
qed
}
ultimately
show "is_partition cs = is_partition_alt cs" by auto
qed
lemma is_partition_Nil: "is_partition [] = True" unfolding is_partition_def by
auto
lemma is_partition_Cons:
"is_partition(x#xs) = (is_partition xs \<and> x \<inter> \<Union>set xs = {})"
(is "?l = ?r")
proof
assume ?l
have one: "is_partition xs"
proof (unfold is_partition_def, intro allI impI)
fix j i assume "j < length xs" and "i < j"
hence "Suc j < length(x#xs)" and "Suc i < Suc j" by auto
from `?l`[unfolded is_partition_def,THEN spec,THEN mp,THEN spec,THEN mp,OF
this]
have "(x#xs)!(Suc i) \<inter> (x#xs)!(Suc j) = {}" .
thus "xs!i \<inter> xs!j = {}" by simp
qed
have two: "x \<inter> \<Union>set xs = {}"
proof (rule ccontr)
assume "x \<inter> \<Union>set xs \<noteq> {}"
then obtain y where "y \<in> x" and "y \<in> \<Union>set xs" by auto
then obtain z where "z \<in> set xs" and "y \<in> z" by auto
then obtain i where "i < length xs" and "xs!i = z" using in_set_conv_nth[of
z xs] by auto
with `y \<in> z` have "y \<in> (x#xs)!Suc i" by auto
moreover with `y \<in> x` have "y \<in> (x#xs)!0" by simp
ultimately have "(x#xs)!0 \<inter> (x#xs)!Suc i \<noteq> {}" by auto
moreover from `i < length xs` have "Suc i < length(x#xs)" by simp
ultimately show False using `?l`[unfolded is_partition_def] by best
qed
from one two show ?r ..
next
assume ?r
show ?l
proof (unfold is_partition_def, intro allI impI)
fix j i
assume j: "j < length (x # xs)"
assume i: "i < j"
from i obtain j' where j': "j = Suc j'" by (cases j, auto)
with j have j'len: "j' < length xs" and j'elem: "(x # xs) ! j = xs ! j'" by
auto
show "(x # xs) ! i \<inter> (x # xs) ! j = {}"
proof (cases i)
case 0
with j'elem have "(x # xs) ! i \<inter> (x # xs) ! j = x \<inter> xs !
j'" by auto
also have "\<dots> \<subseteq> x \<inter> \<Union>set xs" using j'len by
force
finally show ?thesis using `?r` by auto
next
case (Suc i')
with i j' have i'j': "i' < j'" by auto
from Suc j' have "(x # xs) ! i \<inter> (x # xs) ! j = xs ! i' \<inter>
xs ! j'" by auto
with `?r` i'j' j'len show ?thesis unfolding is_partition_def by auto
qed
qed
qed
subsection {*merging functions*}
definition fun_merge :: "('a \<Rightarrow> 'b)list \<Rightarrow> 'a set list
\<Rightarrow> 'a \<Rightarrow> 'b"
where "fun_merge fs as a \<equiv> (fs ! (LEAST i. i < length as \<and> a
\<in> as ! i)) a"
lemma fun_merge: assumes
i: "i < length as"
and a: "a \<in> as ! i"
and ident: "\<And> i j a. i < length as \<Longrightarrow> j < length as
\<Longrightarrow> a \<in> as ! i \<Longrightarrow> a \<in> as ! j
\<Longrightarrow> (fs ! i) a = (fs ! j) a"
shows "fun_merge fs as a = (fs ! i) a"
proof -
let ?p = "\<lambda> i. i < length as \<and> a \<in> as ! i"
let ?l = "LEAST i. ?p i"
have p: "?p ?l"
by (rule LeastI, insert i a, auto)
show ?thesis unfolding fun_merge_def
by (rule ident[OF _ i _ a], insert p, auto)
qed
lemma fun_merge_part: assumes
part: "is_partition as"
and i: "i < length as"
and a: "a \<in> as ! i"
shows "fun_merge fs as a = (fs ! i) a"
proof(rule fun_merge[OF i a])
fix i j a
assume "i < length as" and "j < length as" and "a \<in> as ! i" and "a \<in>
as ! j"
hence "i = j" using part[unfolded is_partition_alt is_partition_alt_def] by
(cases "i = j", auto)
thus "(fs ! i) a = (fs ! j) a" by simp
qed
subsection {* assignments from key-value pairs *}
fun enum_vectors :: "'c list \<Rightarrow> 'v list \<Rightarrow> ('v \<times>
'c)list list"
where "enum_vectors C [] = [[]]"
| "enum_vectors C (x # xs) = (let rec = enum_vectors C xs in concat (map
(\<lambda> vec. map (\<lambda> c. (x,c) # vec) C) rec))"
definition fun_of :: "('v \<times> 'c)list \<Rightarrow> 'v \<Rightarrow> 'c"
where [simp]: "fun_of vec x = the (lookup x vec)"
lemma enum_vectors_complete: assumes "C \<noteq> []"
shows "\<exists> vec \<in> set (enum_vectors C xs). \<forall> x \<in> set xs.
\<forall> c \<in> set C. \<alpha> x = c \<longrightarrow> fun_of vec x = c"
proof (induct xs, simp)
case (Cons x xs)
from this obtain vec where enum: "vec \<in> set (enum_vectors C xs)" and eq:
"\<forall> x \<in> set xs. \<forall> c \<in> set C. \<alpha> x = c
\<longrightarrow> fun_of vec x = c" by auto
from enum have res: "set (map (\<lambda> c. (x,c) # vec) C) \<subseteq> set
(enum_vectors C (x # xs)) " (is "_ \<subseteq> ?res") by auto
show ?case
proof (cases "\<alpha> x \<in> set C")
case False
from assms have "hd C \<in> set C" by auto
with res have elem: "(x,hd C) # vec \<in> ?res" (is "?vec \<in> _") by auto
from eq False have "\<forall> y \<in> set (x # xs). \<forall> c \<in> set
C. \<alpha> y = c \<longrightarrow> fun_of ?vec y = c" by auto
with elem show ?thesis by blast
next
case True
with res have elem: "(x, \<alpha> x) # vec \<in> ?res" (is "?vec \<in> _")
by auto
from eq True have "\<forall> y \<in> set (x # xs). \<forall> c \<in> set C.
\<alpha> y = c \<longrightarrow> fun_of ?vec y = c" by auto
with elem show ?thesis by blast
qed
qed
lemma enum_vectors_sound: assumes "y \<in> set xs" and "vec \<in> set
(enum_vectors C xs)"
shows "fun_of vec y \<in> set C"
using assms
proof (induct xs arbitrary: vec, simp)
case (Cons x xs vec)
from Cons(3) obtain v vecc where vec: "vec = v # vecc" by auto
note C3 = Cons(3)[unfolded vec enum_vectors.simps Let_def]
from C3 have vecc: "vecc \<in> set (enum_vectors C xs)" by auto
from C3 obtain c where v: "v = (x,c)" and c: "c \<in> set C" by auto
show ?case
proof (cases "y = x")
case True
show ?thesis unfolding vec v True using c by auto
next
case False
with Cons(2) have y: "y \<in> set xs" by auto
from False have id: "fun_of vec y = fun_of vecc y"
unfolding vec v by auto
show ?thesis unfolding id
by (rule Cons(1)[OF y vecc])
qed
qed
declare fun_of_def[simp del]
lemma fun_of_concat: assumes mem: "x \<in> set (map fst (\<tau>s i))"
and i: "i < n"
and ident: "\<And> i j. i < n \<Longrightarrow> j < n \<Longrightarrow> x
\<in> set (map fst (\<tau>s i)) \<Longrightarrow> x \<in> set (map fst (\<tau>s
j)) \<Longrightarrow> fun_of (\<tau>s i) x = fun_of (\<tau>s j) x"
shows "fun_of (concat (map \<tau>s [0..<n])) x = fun_of (\<tau>s i) x"
using assms
proof (induct n arbitrary: i \<tau>s)
case 0
thus ?case by simp
next
case (Suc n i \<tau>s) note IH = this
let ?\<tau>s = "\<lambda>i. \<tau>s (Suc i)"
have id: "concat (map \<tau>s [0..<Suc n]) = \<tau>s 0 @ concat (map ?\<tau>s
[0..<n])" unfolding map_nth_Suc by simp
let ?l = "lookup x (\<tau>s 0)"
show ?case
proof (cases i)
case 0
with IH(2) have x: "x \<in> set (map fst (\<tau>s 0))" by auto
then obtain y where xy: "(x,y) \<in> set (\<tau>s 0)" by auto
from lookup_NoneD[of x "\<tau>s 0"] xy have "?l \<noteq> None" by auto
then obtain y where look: "?l = Some y" by (cases "\<tau>s 0", auto)
show ?thesis unfolding 0 fun_of_def id look lookup_append_Some[OF look] by
simp
next
case (Suc j)
with IH(3)
have 0: "0 < i" and j: "j < n" by auto
show ?thesis
proof (cases "x \<in> set (map fst (\<tau>s 0))")
case False
have l: "?l = None"
proof (cases "?l")
case (Some y)
from lookup_SomeD[OF this] False show ?thesis by force
qed simp
show ?thesis unfolding fun_of_def id lookup_append_None[OF l]
unfolding fun_of_def[symmetric] Suc
proof (rule IH(1)[OF _ j])
show "x \<in> set (map fst (\<tau>s (Suc j)))" using IH(2) unfolding
Suc .
next
fix i j
assume "i < n" and "j < n" and "x \<in> set (map fst (\<tau>s (Suc
i)))" and "x \<in> set (map fst (\<tau>s (Suc j)))"
thus "fun_of (\<tau>s (Suc i)) x = fun_of (\<tau>s (Suc j)) x"
using IH(4)[of "Suc i" "Suc j"] by auto
qed
next
case True
then obtain y where xy: "(x,y) \<in> set (\<tau>s 0)" by auto
from lookup_NoneD[of x "\<tau>s 0"] xy have "?l \<noteq> None" by auto
then obtain y where look: "?l = Some y" by (cases "\<tau>s 0", auto)
have "fun_of (concat (map \<tau>s [0..<Suc n])) x = fun_of (\<tau>s 0) x"
unfolding id fun_of_def look
lookup_append_Some[OF look] by simp
also have "... = fun_of (\<tau>s i) x"
proof (rule IH(4)[OF _ IH(3)])
from xy show "x \<in> set (map fst (\<tau>s 0))" by force
next
from IH(2) show "x \<in> set (map fst (\<tau>s i))" by force
qed simp
finally show ?thesis .
qed
qed
qed
lemma fun_of_concat_part: assumes mem: "x \<in> set (map fst (\<tau>s i))"
and i: "i < n"
and partition: "is_partition (map (\<lambda> i. set (map fst (\<tau>s i)))
[0..<n])"
shows "fun_of (concat (map \<tau>s [0..<n])) x = fun_of (\<tau>s i) x"
proof (rule fun_of_concat, rule mem, rule i)
fix i j
assume "i < n" and "j < n" and "x \<in> set (map fst (\<tau>s i))" and "x
\<in> set (map fst (\<tau>s j))"
hence "i = j" using partition[unfolded is_partition_alt is_partition_alt_def]
by (cases "i = j", auto)
thus "fun_of (\<tau>s i) x = fun_of (\<tau>s j) x" by simp
qed
lemma fun_of_concat_merge: assumes "\<And> i. i < length ts \<Longrightarrow> x
\<in> h (ts ! i) \<Longrightarrow> fun_of (f i) x = (g ! i) x"
and "length ts = length g"
and "\<And> i. i < length ts \<Longrightarrow> (lookup x (f i) \<noteq> None)
= (x \<in> h (ts ! i))"
and "x \<in> h (ts ! i)"
and "i < length ts"
shows "fun_of (concat (map f [0..<length ts])) x = fun_merge g (map h ts) x"
using assms
unfolding fun_merge_def fun_of_def
proof (induct ts arbitrary: i f g)
case Nil
thus ?case by simp
next
case (Cons xy ts)
let ?p' = "\<lambda> ts i. i < length (map h ts) \<and> x \<in> map h ts ! i"
let ?p = "?p' (xy # ts)"
let ?P = "?p' ts"
let ?L = "LEAST i. ?p i"
have id: "the (lookup x (concat (map f [0..<length (xy # ts)]))) =
the (lookup x (f 0 @ concat (map (\<lambda> i. f (Suc i)) [0..<length
ts])))" (is "?l = the (lookup x ( _ @ ?l'))")
by (simp add: map_nth_Suc del: upt_Suc)
show ?case
proof (cases "lookup x (f 0)")
case (Some y)
from lookup_append_Some[OF Some]
have ly: "?l = y" unfolding id Some by simp
have "?p 0" using Cons(4)[of 0] using Some by auto
hence L0: "?L = 0"
by (rule Least_equality, simp)
from Cons(4)[of 0] Some have x: "x \<in> h xy" by auto
show ?thesis unfolding ly L0 using Cons(2)[of 0, unfolded Some] x by simp
next
case None
from lookup_append_None[OF None]
have ll: "?l = the (lookup x ?l')" unfolding id by simp
from Cons(4)[of 0] None have x: "x \<notin> h xy" by auto
hence p0: "\<not> ?p 0" by simp
from Cons(5) Cons(6) have pI: "?p i" unfolding nth_map[OF Cons(6)] by simp
from Least_Suc[of ?p, OF pI p0] have L: "?L = Suc (LEAST m. ?P m)" by simp
from Cons(3) obtain a g' where g: "g = a # g'" by (cases g, auto)
from Cons(5) x obtain j where i: "i = Suc j" by (cases i, auto)
show ?thesis unfolding ll L g nth_Cons_Suc
proof (rule Cons(1))
from g Cons(3) show "length ts = length g'" by auto
next
from Cons(5) i show "x \<in> h (ts ! j)" by auto
next
from Cons(6) i show "j < length ts" by auto
next
fix m
assume "m < length ts"
thus "(lookup x (f (Suc m)) \<noteq> None) = (x \<in> h (ts ! m))"
using Cons(4)[of "Suc m"] by auto
next
fix m
assume "m < length ts" and "x \<in> h (ts ! m)"
thus "the (lookup x (f (Suc m))) = (g' ! m) x"
using Cons(2)[of "Suc m"] unfolding g by auto
qed
qed
qed
subsection {* Miscellaneous *}
lemma infinite_imp_elem: "\<not> finite A \<Longrightarrow> \<exists> x. x
\<in> A"
by (cases "A = {}", auto)
lemma inf_pigeonhole_principle:
assumes "\<forall>k::nat. \<exists>i<n::nat. f k i"
shows "\<exists>i<n. \<forall>k. \<exists>k'\<ge>k. f k' i"
proof -
have nfin: "~ finite (UNIV :: nat set)" by auto
have fin: "finite ({i. i < n})" by auto
from pigeonhole_infinite_rel[OF nfin fin] assms
obtain i where i: "i < n" and nfin: "\<not> finite {a. f a i}" by auto
show ?thesis
proof (intro exI conjI, rule i, intro allI)
fix k
have "finite {a. f a i \<and> a < k}" by auto
with nfin have "\<not> finite ({a. f a i} - {a. f a i \<and> a < k})" by
auto
from infinite_imp_elem[OF this]
obtain a where "f a i" and "a \<ge> k" by auto
thus "\<exists> k' \<ge> k. f k' i" by force
qed
qed
subsection {*Combinators*}
definition const :: "'a \<Rightarrow> 'b \<Rightarrow> 'a" where
"const \<equiv> (\<lambda>x y. x)"
definition flip :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> ('b
\<Rightarrow> 'a \<Rightarrow> 'c)" where
"flip f \<equiv> (\<lambda>x y. f y x)"
declare flip_def[simp]
lemma const_apply[simp]: "const x y = x"
by (simp add: const_def)
lemma foldr_Cons [simp]:
"foldr op # xs ys = xs @ ys"
by (induct xs) simp_all
lemma foldl_flip_Cons[simp]:
"foldl (flip op #) xs ys = rev ys @ xs"
by (induct ys arbitrary: xs) simp_all
(*FIXME: already present as List.foldl_foldr, but
direction seems odd.*)
lemma foldr_flip_rev[simp]:
"foldr (flip f) (rev xs) a = foldl f a xs"
by (simp add: foldr_foldl)
(*FIXME: already present as List.foldr_foldr, but
direction seems odd.*)
lemma foldl_flip_rev[simp]:
"foldl (flip f) a (rev xs) = foldr f xs a"
by (simp add: foldl_foldr)
(*FIXME: available in HOL library?*)
interpretation o!: semigroup_add "op \<circ>"
by (unfold_locales) (simp add: o_assoc)
lemma foldl_assoc:
fixes b :: "('a \<Rightarrow> 'a) \<Rightarrow> ('a \<Rightarrow> 'a)
\<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<cdot>" 55)
assumes "\<And>f g h. f \<cdot> (g \<cdot> h) = f \<cdot> g \<cdot> h"
shows "foldl op \<cdot> (x \<cdot> y) zs = x \<cdot> foldl op \<cdot> y zs"
proof -
interpret semigroup_add b by (unfold_locales) (simp add: assms)
show ?thesis by (simp add: foldl_assoc)
qed
lemma foldr_assoc:
assumes "\<And>f g h. b (b f g) h = b f (b g h)"
shows "foldr b xs (b y z) = b (foldr b xs y) z"
using assms by (induct xs) simp_all
lemma foldl_foldr_o_id:
"foldl op \<circ> id fs = foldr op \<circ> fs id"
proof (induct fs)
case Nil show ?case by simp
next
case (Cons f fs)
have "id \<circ> f = f \<circ> id" by simp
with Cons [symmetric] show ?case
by (simp only: foldl_Cons List.foldr_Cons o_apply [of _ _ id] foldl_assoc
o_assoc)
qed
lemma foldr_o_o_id[simp]:
"foldr (op \<circ> \<circ> f) xs id a = foldr f xs a"
by (induct xs) simp_all
subsection {* For IsaFoR *}
fun debug :: "string \<Rightarrow> string \<Rightarrow> 'a \<Rightarrow> 'a"
where "debug i t x = x"
end
_______________________________________________
isabelle-dev mailing list
isabelle-...@in.tum.de
https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev