Up to index of Isabelle/HOL/Tables
theory Utils = Main:header {* Utilities *} theory Utils = Main: text {* The following variant of modus ponens is useful as erule, for example for preparing local inductions. *} lemma mp1: "\<lbrakk> P; P \<longrightarrow> Q \<rbrakk> \<Longrightarrow> Q" by simp subsection {* Functions *} subsubsection {* Combinators *} consts const :: "'a \<Rightarrow> 'b \<Rightarrow> 'a" defs const_def: "const == % x y . x" lemma const[simp]: "const x y = x" by (simp add: const_def) lemma const_expand: "const c = (% x . c)" by (rule ext, simp) consts flip :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> ('b \<Rightarrow> 'a \<Rightarrow> 'c)" defs flip_def[simp]: "flip f x y == f y x" subsubsection {* Currying *} constdefs curry :: "(('a * 'b) \<Rightarrow> 'c) \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'c" "curry f == % a b . f (a,b)" uncurry :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> ('a * 'b) \<Rightarrow> 'c" "uncurry g == % p . g (fst p) (snd p)" lemma curry[simp]: "curry f a b = f (a,b)" by (simp add: curry_def) lemma uncurry[simp]: "uncurry g (a,b) = g a b" by (simp add: uncurry_def) lemma uncurry_lambda2[simp]: "uncurry (\<lambda>h t. F h t) = (\<lambda>p . F (fst p) (snd p))" by (simp add: uncurry_def) lemma uncurry_K2[simp]: "uncurry (\<lambda>h t. F h) = (\<lambda>p . F (fst p))" by simp lemma uncurry_K[simp]: "uncurry (\<lambda>h. F) = (\<lambda>p . F (snd p))" by simp subsubsection {* Pair Manipulation *} constdefs pupd1 :: "('a \<Rightarrow> 'b) \<Rightarrow> ('a * 'c) \<Rightarrow> ('b * 'c)" "pupd1 f p == (f (fst p), snd p)" pupd2 :: "('a \<Rightarrow> 'b) \<Rightarrow> ('c * 'a) \<Rightarrow> ('c * 'b)" "pupd2 g p == (fst p, g (snd p))" lemma pupd1[simp]: "pupd1 f (x,y) = (f x, y)" by (simp add: pupd1_def) lemma pupd2[simp]: "pupd2 g (x,y) = (x, g y)" by (simp add: pupd2_def) subsubsection {* Extensionality *} text {* I had some problems applying @{text "HOL.ext"} directly.*} lemma f_ext: assumes eq: "\<And> x . f x = g x" shows "f = g" by (rule HOL.ext) subsection {* Function Properties *} subsubsection {* Associativity *} constdefs assoc :: "('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> bool" "assoc f == (ALL x y z . f (f x y) z = f x (f y z))" lemma assoc[simp]: "assoc f \<Longrightarrow> f (f x y) z = f x (f y z)" by (unfold assoc_def, auto) lemma assoc_intro[intro?]: "\<lbrakk> \<And> x y z . f (f x y) z = f x (f y z) \<rbrakk> \<Longrightarrow> assoc f" by (unfold assoc_def, auto) (* lemma assoc_const[simp]: "assoc (% x y . x)" by (rule assoc_intro, simp) *) lemma const_assoc[simp]: "assoc const" by (rule assoc_intro, simp) subsubsection {* Idempotence *} constdefs idempotent :: "('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> bool" "idempotent f == (ALL x . f x x = x)" lemma idempotent[simp]: "idempotent f \<Longrightarrow> f x x = x" by (unfold idempotent_def, auto) lemma idempotent_intro[intro?]: "\<lbrakk> \<And> x . f x x = x \<rbrakk> \<Longrightarrow> idempotent f" by (unfold idempotent_def, auto) subsubsection {* Commutativity *} constdefs commutative :: "('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> bool" "commutative f == (ALL x y . f x y = f y x)" lemma commutative: "commutative f \<Longrightarrow> f x y = f y x" by (unfold commutative_def, auto) lemma commutative_intro[intro?]: "\<lbrakk> \<And> x y . f x y = f y x \<rbrakk> \<Longrightarrow> commutative f" by (unfold commutative_def, auto) subsubsection {* Units *} consts LRunit :: "('a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'bool" defs LRunit_def: "LRunit f u == ALL y . f u y = y & f y u = y" lemma LRunit_left: "LRunit f u \<Longrightarrow> f u x = x" by (unfold LRunit_def, simp) lemma LRunit_right: "LRunit f u \<Longrightarrow> f x u = x" by (unfold LRunit_def, simp) lemma LRunit_equal: assumes u[intro,simp]: "LRunit f u" assumes v[intro,simp]: "LRunit f v" shows "u = v" proof - have "u = f u v" by (rule sym, rule LRunit_right, simp) also have "f u v = v" by (rule LRunit_left, simp) finally show ?thesis . qed lemma LRunit_const: "ALL x . LRunit c (F x) \<Longrightarrow> F x = F arbitrary" apply (subgoal_tac "ALL x y . F x = F y", simp) apply (intro strip) apply (rule LRunit_equal [of c]) apply simp_all done subsection {* Additional Material for Lists *} lemma foldr_append: "foldr f (xs @ ys) z = foldr f xs (foldr f ys z)" by (induct_tac xs, auto) consts foldr_1 :: "('a \<Rightarrow> 'a \<Rightarrow> 'a) * 'a list \<Rightarrow> 'a" recdef foldr_1 "measure (% (f,xs) . length xs)" foldr_1_sing[simp]: "foldr_1 (f, x # []) = x" foldr_1_cons0[simp]: "foldr_1 (f, x # y # ys) = f x (foldr_1 (f, y # ys))" lemma foldr_1_cons[simp]: "\<lbrakk> xs ~= [] \<rbrakk> \<Longrightarrow> foldr_1 (f, x # xs) = f x (foldr_1 (f, xs))" by (cases xs, auto) lemma foldr_1_append_distr_0: "assoc f \<Longrightarrow> (ALL x ys . ys ~= [] \<longrightarrow> foldr_1 (f, x # xs @ ys) = f (foldr_1 (f, x # xs)) (foldr_1 (f, ys)))" by (induct_tac xs, auto) lemma foldr_1_append_distr: assumes xs[simp]: "xs ~= []" assumes ys[simp]: " ys ~= []" assumes f[simp]: "assoc f" shows "foldr_1 (f, xs @ ys) = f (foldr_1 (f, xs)) (foldr_1 (f, ys))" proof (cases xs) case Nil thus ?thesis by simp next case Cons thus ?thesis by (insert foldr_1_append_distr_0 [of f "tl xs"], simp) qed lemma mem_append[simp]: "x mem (xs @ ys) = (x mem xs | x mem ys)" by (induct_tac xs, simp_all) constdefs zipWith :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> 'a list \<Rightarrow> 'b list \<Rightarrow> 'c list" "zipWith f xs ys == map (uncurry f) (zip xs ys)" lemma zipWith_Cons[simp]: "zipWith f (x#xs) (y#ys) = f x y # zipWith f xs ys" by (simp add: zipWith_def) lemma zipWith_Nil_1[simp]: "zipWith f [] ys = []" by (simp add: zipWith_def) lemma zipWith_Nil_2[simp]: "zipWith f xs [] = []" by (simp add: zipWith_def) lemma zipWith_assoc_0: "assoc f \<Longrightarrow> ALL ys zs . zipWith f (zipWith f xs ys) zs = zipWith f xs (zipWith f ys zs)" apply (induct_tac xs, simp) apply (intro strip) apply (induct_tac ys, simp) apply (induct_tac zs, simp) apply simp done lemma zipWith_assoc[simp]: "assoc f \<Longrightarrow> zipWith f (zipWith f xs ys) zs = zipWith f xs (zipWith f ys zs)" by (insert zipWith_assoc_0, auto) lemma assoc_zipWith[simp]: "assoc f \<Longrightarrow> assoc (zipWith f)" by (rule assoc_intro, simp) subsection {* Option Utilities *} consts option :: "'b \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'a option \<Rightarrow> 'b" primrec option_N: "option r f None = r" option_S: "option r f (Some a) = f a" subsubsection {* The Option Monad *} consts optThen :: "'a option \<Rightarrow> ('a \<Rightarrow> 'b option) \<Rightarrow> 'b option" primrec optThen_N: "optThen None = (% f . None)" optThen_S: "optThen (Some x) = (% f . f x)" declare optThen_N[simp del] declare optThen_S[simp del] lemma optThen_N_f[simp]: "optThen None f = None" by (simp add: optThen_N) lemma optThen_S_f[simp]: "optThen (Some x) f = f x" by (simp add: optThen_S) lemma optThen_result_Some[simp]: "optThen m f = Some x \<Longrightarrow> EX y . m = Some y & f y = Some x" by (cases m, simp_all) lemma optThen_option_map[simp]: "optThen (option_map f x) g = optThen x (g o f)" by (cases x, simp_all) lemma optThen_assoc[simp]: "optThen (optThen x f) g = optThen x (% x . optThen (f x) g)" by (cases x, simp_all) subsubsection {* Equality Option Collapse *} consts optEq :: "'a option \<Rightarrow> 'a option \<Rightarrow> 'a option" primrec optEq_N: "optEq None = (% my . None)" optEq_S: "optEq (Some x) = option None (% y . if (x=y) then Some x else None)" declare optEq_N[simp del] declare optEq_S[simp del] lemma optEq_S_S[simp]: "optEq (Some x) (Some y) = (if (x=y) then Some x else None)" by (simp add: optEq_S) lemma optEq_S_N[simp]: "optEq (Some x) None = None" by (simp add: optEq_S) lemma optEq_N_S[simp]: "optEq None (Some x) = None" by (simp add: optEq_N) lemma optEq_N_N[simp]: "optEq None None = None" by (simp add: optEq_N) lemma optEq_assoc[simp]: "optEq (optEq a b) c = optEq a (optEq b c)" apply (cases a, simp add: optEq_N) apply (cases b, simp add: optEq_N) apply (cases c, simp add: optEq_N) apply simp done lemma assoc_optEq[simp]: "assoc optEq" by (rule assoc_intro, simp) lemma optEq_idempotent[simp]: "idempotent optEq" by (rule idempotent_intro, case_tac x, simp_all) (* premise x=0 not available to simp --- why??? lemma optEq_commutative_0: "optEq x y = optEq y x" proof (cases x) case None thus ?thesis proof (cases y) case None thus ?thesis apply simp *) lemma optEq_commutative[simp]: "commutative optEq" apply (rule commutative_intro) apply (case_tac x, case_tac y, simp_all add: optEq_N optEq_S) apply (case_tac y, simp_all add: optEq_N optEq_S) done end
lemma mp1:
[| P; P --> Q |] ==> Q
lemma const:
const x y = x
lemma const_expand:
const c = (%x. c)
lemma curry:
curry f a b = f (a, b)
lemma uncurry:
uncurry g (a, b) = g a b
lemma uncurry_lambda2:
uncurry F = (%p. F (fst p) (snd p))
lemma uncurry_K2:
uncurry (%h t. F h) = (%p. F (fst p))
lemma uncurry_K:
uncurry (%h. F) = (%p. F (snd p))
lemma pupd1:
pupd1 f (x, y) = (f x, y)
lemma pupd2:
pupd2 g (x, y) = (x, g y)
lemma
(!!x. f x = g x) ==> f = g
lemma assoc:
assoc f ==> f (f x y) z = f x (f y z)
lemma assoc_intro:
(!!x y z. f (f x y) z = f x (f y z)) ==> assoc f
lemma const_assoc:
assoc const
lemma idempotent:
idempotent f ==> f x x = x
lemma idempotent_intro:
(!!x. f x x = x) ==> idempotent f
lemma commutative:
commutative f ==> f x y = f y x
lemma commutative_intro:
(!!x y. f x y = f y x) ==> commutative f
lemma LRunit_left:
LRunit f u ==> f u x = x
lemma LRunit_right:
LRunit f u ==> f x u = x
lemma
[| LRunit f u; LRunit f v |] ==> u = v
lemma LRunit_const:
ALL x. LRunit c (F x) ==> F x = F arbitrary
lemma foldr_append:
foldr f (xs @ ys) z = foldr f xs (foldr f ys z)
lemma foldr_1_cons:
xs ~= [] ==> foldr_1 (f, x # xs) = f x (foldr_1 (f, xs))
lemma foldr_1_append_distr_0:
assoc f ==> ALL x ys. ys ~= [] --> foldr_1 (f, x # xs @ ys) = f (foldr_1 (f, x # xs)) (foldr_1 (f, ys))
lemma
[| xs ~= []; ys ~= []; assoc f |] ==> foldr_1 (f, xs @ ys) = f (foldr_1 (f, xs)) (foldr_1 (f, ys))
lemma mem_append:
x mem xs @ ys = (x mem xs | x mem ys)
lemma zipWith_Cons:
zipWith f (x # xs) (y # ys) = f x y # zipWith f xs ys
lemma zipWith_Nil_1:
zipWith f [] ys = []
lemma zipWith_Nil_2:
zipWith f xs [] = []
lemma zipWith_assoc_0:
assoc f ==> ALL ys zs. zipWith f (zipWith f xs ys) zs = zipWith f xs (zipWith f ys zs)
lemma zipWith_assoc:
assoc f ==> zipWith f (zipWith f xs ys) zs = zipWith f xs (zipWith f ys zs)
lemma assoc_zipWith:
assoc f ==> assoc (zipWith f)
lemma optThen_N_f:
optThen None f = None
lemma optThen_S_f:
optThen (Some x) f = f x
lemma optThen_result_Some:
optThen m f = Some x ==> EX y. m = Some y & f y = Some x
lemma optThen_option_map:
optThen (option_map f x) g = optThen x (g o f)
lemma optThen_assoc:
optThen (optThen x f) g = optThen x (%x. optThen (f x) g)
lemma optEq_S_S:
optEq (Some x) (Some y) = (if x = y then Some x else None)
lemma optEq_S_N:
optEq (Some x) None = None
lemma optEq_N_S:
optEq None (Some x) = None
lemma optEq_N_N:
optEq None None = None
lemma optEq_assoc:
optEq (optEq a b) c = optEq a (optEq b c)
lemma assoc_optEq:
assoc optEq
lemma optEq_idempotent:
idempotent optEq
lemma optEq_commutative:
commutative optEq