# HG changeset patch # User traytel # Date 1380713344 -7200 # Node ID e5853a648b59b1855d02b13c130d3065fcd77bb5 # Parent 82d9b2701a036727f05f52313a290f4e540a4820 use new coinduction method and primcorec in examples diff -r 82d9b2701a03 -r e5853a648b59 src/HOL/BNF/Examples/Derivation_Trees/Prelim.thy --- a/src/HOL/BNF/Examples/Derivation_Trees/Prelim.thy Wed Oct 02 11:57:52 2013 +0200 +++ b/src/HOL/BNF/Examples/Derivation_Trees/Prelim.thy Wed Oct 02 13:29:04 2013 +0200 @@ -28,9 +28,6 @@ abbreviation sum_case_abbrev ("[[_,_]]" 800) where "[[f,g]] \ Sum_Type.sum_case f g" -lemma inj_Inl[simp]: "inj Inl" unfolding inj_on_def by auto -lemma inj_Inr[simp]: "inj Inr" unfolding inj_on_def by auto - lemma Inl_oplus_elim: assumes "Inl tr \ (id \ f) ` tns" shows "Inl tr \ tns" diff -r 82d9b2701a03 -r e5853a648b59 src/HOL/BNF/Examples/Koenig.thy --- a/src/HOL/BNF/Examples/Koenig.thy Wed Oct 02 11:57:52 2013 +0200 +++ b/src/HOL/BNF/Examples/Koenig.thy Wed Oct 02 13:29:04 2013 +0200 @@ -23,13 +23,6 @@ apply (auto simp add: stl_def) by (simp add: Stream_def stream.dtor_ctor) -lemma unfold_pair_fun_shd[simp]: "shd (stream_dtor_unfold (f \ g) t) = f t" -unfolding shd_def' pair_fun_def stream.dtor_unfold by simp - -lemma unfold_pair_fun_stl[simp]: "stl (stream_dtor_unfold (f \ g) t) = - stream_dtor_unfold (f \ g) (g t)" -unfolding stl_def' pair_fun_def stream.dtor_unfold by simp - (* infinite trees: *) coinductive infiniteTr where "\tr' \ listF_set (sub tr); infiniteTr tr'\ \ infiniteTr tr" @@ -50,13 +43,9 @@ "infiniteTr tr \ (\ tr' \ listF_set (sub tr). infiniteTr tr')" by (erule infiniteTr.cases) blast -definition "konigPath \ stream_dtor_unfold - (lab \ (\tr. SOME tr'. tr' \ listF_set (sub tr) \ infiniteTr tr'))" - -lemma konigPath_simps[simp]: -"shd (konigPath t) = lab t" -"stl (konigPath t) = konigPath (SOME tr. tr \ listF_set (sub t) \ infiniteTr tr)" -unfolding konigPath_def by simp+ +primcorec konigPath where + "shd (konigPath t) = lab t" +| "stl (konigPath t) = konigPath (SOME tr. tr \ listF_set (sub t) \ infiniteTr tr)" (* proper paths in trees: *) coinductive properPath where @@ -97,16 +86,14 @@ proof- {fix as assume "infiniteTr tr \ as = konigPath tr" hence "properPath as tr" - proof (induct rule: properPath_coind, safe) - fix t - let ?t = "SOME t'. t' \ listF_set (sub t) \ infiniteTr t'" - assume "infiniteTr t" - hence "\t' \ listF_set (sub t). infiniteTr t'" by simp - hence "\t'. t' \ listF_set (sub t) \ infiniteTr t'" by blast - hence "?t \ listF_set (sub t) \ infiniteTr ?t" by (elim someI_ex) - moreover have "stl (konigPath t) = konigPath ?t" by simp - ultimately show "\t' \ listF_set (sub t). - infiniteTr t' \ stl (konigPath t) = konigPath t'" by blast + proof (coinduction arbitrary: tr as rule: properPath_coind) + case (sub tr as) + let ?t = "SOME t'. t' \ listF_set (sub tr) \ infiniteTr t'" + from sub have "\t' \ listF_set (sub tr). infiniteTr t'" by simp + then have "\t'. t' \ listF_set (sub tr) \ infiniteTr t'" by blast + then have "?t \ listF_set (sub tr) \ infiniteTr ?t" by (rule someI_ex) + moreover have "stl (konigPath tr) = konigPath ?t" by simp + ultimately show ?case using sub by blast qed simp } thus ?thesis using assms by blast @@ -114,38 +101,33 @@ (* some more stream theorems *) -lemma stream_map[simp]: "smap f = stream_dtor_unfold (f o shd \ stl)" -unfolding smap_def pair_fun_def shd_def'[abs_def] stl_def'[abs_def] - map_pair_def o_def prod_case_beta by simp - -definition plus :: "nat stream \ nat stream \ nat stream" (infixr "\" 66) where - [simp]: "plus xs ys = - stream_dtor_unfold ((%(xs, ys). shd xs + shd ys) \ (%(xs, ys). (stl xs, stl ys))) (xs, ys)" +primcorec plus :: "nat stream \ nat stream \ nat stream" (infixr "\" 66) where + "shd (plus xs ys) = shd xs + shd ys" +| "stl (plus xs ys) = plus (stl xs) (stl ys)" definition scalar :: "nat \ nat stream \ nat stream" (infixr "\" 68) where [simp]: "scalar n = smap (\x. n * x)" -definition ones :: "nat stream" where [simp]: "ones = stream_dtor_unfold ((%x. 1) \ id) ()" -definition twos :: "nat stream" where [simp]: "twos = stream_dtor_unfold ((%x. 2) \ id) ()" +primcorec ones :: "nat stream" where "ones = 1 ## ones" +primcorec twos :: "nat stream" where "twos = 2 ## twos" definition ns :: "nat \ nat stream" where [simp]: "ns n = scalar n ones" lemma "ones \ ones = twos" -by (rule stream.coinduct[of "%x1 x2. \x. x1 = ones \ ones \ x2 = twos"]) auto + by coinduction simp lemma "n \ twos = ns (2 * n)" -by (rule stream.coinduct[of "%x1 x2. \n. x1 = n \ twos \ x2 = ns (2 * n)"]) force+ + by coinduction simp lemma prod_scalar: "(n * m) \ xs = n \ m \ xs" -by (rule stream.coinduct[of "%x1 x2. \n m xs. x1 = (n * m) \ xs \ x2 = n \ m \ xs"]) force+ + by (coinduction arbitrary: xs) auto lemma scalar_plus: "n \ (xs \ ys) = n \ xs \ n \ ys" -by (rule stream.coinduct[of "%x1 x2. \n xs ys. x1 = n \ (xs \ ys) \ x2 = n \ xs \ n \ ys"]) - (force simp: add_mult_distrib2)+ + by (coinduction arbitrary: xs ys) (auto simp: add_mult_distrib2) lemma plus_comm: "xs \ ys = ys \ xs" -by (rule stream.coinduct[of "%x1 x2. \xs ys. x1 = xs \ ys \ x2 = ys \ xs"]) force+ + by (coinduction arbitrary: xs ys) auto lemma plus_assoc: "(xs \ ys) \ zs = xs \ ys \ zs" -by (rule stream.coinduct[of "%x1 x2. \xs ys zs. x1 = (xs \ ys) \ zs \ x2 = xs \ ys \ zs"]) force+ + by (coinduction arbitrary: xs ys zs) auto end diff -r 82d9b2701a03 -r e5853a648b59 src/HOL/BNF/Examples/Process.thy --- a/src/HOL/BNF/Examples/Process.thy Wed Oct 02 11:57:52 2013 +0200 +++ b/src/HOL/BNF/Examples/Process.thy Wed Oct 02 13:29:04 2013 +0200 @@ -71,19 +71,10 @@ subsection{* Single-guard fixpoint definition *} -definition -"BX \ - process_unfold - (\ P. True) - (\ P. ''a'') - (\ P. P) - undefined - undefined - ()" - -lemma BX: "BX = Action ''a'' BX" -unfolding BX_def -using process.unfold(1)[of "\ P. True" "()" "\ P. ''a''" "\ P. P"] by simp +primcorec BX where + "isAction BX" +| "prefOf BX = ''a''" +| "contOf BX = BX" subsection{* Multi-guard fixpoint definitions, simulated with auxiliary arguments *} @@ -172,28 +163,9 @@ definition "guarded sys \ \ X Y. sys X \ VAR Y" -definition -"solution sys \ - process_unfold - (isACT sys) - (PREF sys) - (CONT sys) - (CH1 sys) - (CH2 sys)" - -lemma solution_Action: -assumes "isACT sys T" -shows "solution sys T = Action (PREF sys T) (solution sys (CONT sys T))" -unfolding solution_def -using process.unfold(1)[of "isACT sys" T "PREF sys" "CONT sys" "CH1 sys" "CH2 sys"] - assms by simp - -lemma solution_Choice: -assumes "\ isACT sys T" -shows "solution sys T = Choice (solution sys (CH1 sys T)) (solution sys (CH2 sys T))" -unfolding solution_def -using process.unfold(2)[of "isACT sys" T "PREF sys" "CONT sys" "CH1 sys" "CH2 sys"] - assms by simp +primcorec solution where + "isACT sys T \ solution sys T = Action (PREF sys T) (solution sys (CONT sys T))" +| "_ \ solution sys T = Choice (solution sys (CH1 sys T)) (solution sys (CH2 sys T))" lemma isACT_VAR: assumes g: "guarded sys" @@ -207,13 +179,13 @@ case True hence T: "isACT sys (sys X)" unfolding isACT_VAR[OF g] . show ?thesis - unfolding solution_Action[OF T] using solution_Action[of sys "VAR X"] True g + unfolding solution.ctr(1)[OF T] using solution.ctr(1)[of sys "VAR X"] True g unfolding guarded_def by (cases "sys X", auto) next case False note FFalse = False hence TT: "\ isACT sys (sys X)" unfolding isACT_VAR[OF g] . show ?thesis - unfolding solution_Choice[OF TT] using solution_Choice[of sys "VAR X"] FFalse g + unfolding solution.ctr(2)[OF TT] using solution.ctr(2)[of sys "VAR X"] FFalse g unfolding guarded_def by (cases "sys X", auto) qed @@ -222,29 +194,27 @@ proof- {fix q assume "q = solution sys (PROC p)" hence "p = q" - proof(induct rule: process_coind) + proof (coinduct rule: process_coind) case (iss p p') from isAction_isChoice[of p] show ?case proof assume p: "isAction p" hence 0: "isACT sys (PROC p)" by simp - thus ?thesis using iss not_isAction_isChoice - unfolding solution_Action[OF 0] by auto + thus ?thesis using iss not_isAction_isChoice by auto next assume "isChoice p" hence 0: "\ isACT sys (PROC p)" using not_isAction_isChoice by auto - thus ?thesis using iss isAction_isChoice - unfolding solution_Choice[OF 0] by auto + thus ?thesis using iss isAction_isChoice by auto qed next case (Action a a' p p') hence 0: "isACT sys (PROC (Action a p))" by simp - show ?case using Action unfolding solution_Action[OF 0] by simp + show ?case using Action unfolding solution.ctr(1)[OF 0] by simp next case (Choice p q p' q') hence 0: "\ isACT sys (PROC (Choice p q))" using not_isAction_isChoice by auto - show ?case using Choice unfolding solution_Choice[OF 0] by simp + show ?case using Choice unfolding solution.ctr(2)[OF 0] by simp qed } thus ?thesis by metis @@ -252,11 +222,11 @@ lemma solution_ACT[simp]: "solution sys (ACT a T) = Action a (solution sys T)" -by (metis CONT.simps(3) PREF.simps(3) isACT.simps(3) solution_Action) +by (metis CONT.simps(3) PREF.simps(3) isACT.simps(3) solution.ctr(1)) lemma solution_CH[simp]: "solution sys (CH T1 T2) = Choice (solution sys T1) (solution sys T2)" -by (metis CH1.simps(3) CH2.simps(3) isACT.simps(4) solution_Choice) +by (metis CH1.simps(3) CH2.simps(3) isACT.simps(4) solution.ctr(2)) (* Example: *) diff -r 82d9b2701a03 -r e5853a648b59 src/HOL/BNF/Examples/Stream.thy --- a/src/HOL/BNF/Examples/Stream.thy Wed Oct 02 11:57:52 2013 +0200 +++ b/src/HOL/BNF/Examples/Stream.thy Wed Oct 02 13:29:04 2013 +0200 @@ -101,14 +101,8 @@ lemma sset_streams: assumes "sset s \ A" shows "s \ streams A" -proof (coinduct rule: streams.coinduct[of "\s'. \a s. s' = a ## s \ a \ A \ sset s \ A"]) - case streams from assms show ?case by (cases s) auto -next - fix s' assume "\a s. s' = a ## s \ a \ A \ sset s \ A" - then guess a s by (elim exE) - with assms show "\a l. s' = a ## l \ - a \ A \ ((\a s. l = a ## s \ a \ A \ sset s \ A) \ l \ streams A)" - by (cases s) auto +using assms proof (coinduction arbitrary: s) + case streams then show ?case by (cases s) simp qed @@ -175,9 +169,9 @@ lemma smap_alt: "smap f s = s' \ (\n. f (s !! n) = s' !! n)" (is "?L = ?R") proof assume ?R - thus ?L - by (coinduct rule: stream.coinduct[of "\s1 s2. \n. s1 = smap f (sdrop n s) \ s2 = sdrop n s'", consumes 0]) - (auto intro: exI[of _ 0] simp del: sdrop.simps(2)) + then have "\n. smap f (sdrop n s) = sdrop n s'" + by coinduction (auto intro: exI[of _ 0] simp del: sdrop.simps(2)) + then show ?L using sdrop.simps(1) by metis qed auto lemma stake_invert_Nil[iff]: "stake n s = [] \ n = 0" @@ -218,15 +212,15 @@ qed (metis comp_apply sdrop.simps(1) sdrop_while.simps snth.simps(1)) qed -definition "sfilter P = stream_unfold (shd o sdrop_while (Not o P)) (stl o sdrop_while (Not o P))" +primcorec sfilter where + "shd (sfilter P s) = shd (sdrop_while (Not o P) s)" +| "stl (sfilter P s) = sfilter P (stl (sdrop_while (Not o P) s))" lemma sfilter_Stream: "sfilter P (x ## s) = (if P x then x ## sfilter P s else sfilter P s)" proof (cases "P x") - case True thus ?thesis unfolding sfilter_def - by (subst stream.unfold) (simp add: sdrop_while_Stream) + case True thus ?thesis by (subst sfilter.ctr) (simp add: sdrop_while_Stream) next - case False thus ?thesis unfolding sfilter_def - by (subst (1 2) stream.unfold) (simp add: sdrop_while_Stream) + case False thus ?thesis by (subst (1 2) sfilter.ctr) (simp add: sdrop_while_Stream) qed @@ -243,28 +237,17 @@ subsection {* recurring stream out of a list *} -definition cycle :: "'a list \ 'a stream" where - "cycle = stream_unfold hd (\xs. tl xs @ [hd xs])" - -lemma cycle_simps[simp]: - "shd (cycle u) = hd u" - "stl (cycle u) = cycle (tl u @ [hd u])" - by (auto simp: cycle_def) - +primcorec cycle :: "'a list \ 'a stream" where + "shd (cycle xs) = hd xs" +| "stl (cycle xs) = cycle (tl xs @ [hd xs])" lemma cycle_decomp: "u \ [] \ cycle u = u @- cycle u" -proof (coinduct rule: stream.coinduct[of "\s1 s2. \u. s1 = cycle u \ s2 = u @- cycle u \ u \ []", consumes 0, case_names _ Eq_stream]) - case (Eq_stream s1 s2) - then obtain u where "s1 = cycle u \ s2 = u @- cycle u \ u \ []" by blast - thus ?case using stream.unfold[of hd "\xs. tl xs @ [hd xs]" u] by (auto simp: cycle_def) -qed auto +proof (coinduction arbitrary: u) + case Eq_stream then show ?case using stream.collapse[of "cycle u"] + by (auto intro!: exI[of _ "tl u @ [hd u]"]) +qed lemma cycle_Cons[code]: "cycle (x # xs) = x ## cycle (xs @ [x])" -proof (coinduct rule: stream.coinduct[of "\s1 s2. \x xs. s1 = cycle (x # xs) \ s2 = x ## cycle (xs @ [x])", consumes 0, case_names _ Eq_stream]) - case (Eq_stream s1 s2) - then obtain x xs where "s1 = cycle (x # xs) \ s2 = x ## cycle (xs @ [x])" by blast - thus ?case - by (auto simp: cycle_def intro!: exI[of _ "hd (xs @ [x])"] exI[of _ "tl (xs @ [x])"] stream.unfold) -qed auto + by (subst cycle.ctr) simp lemma cycle_rotated: "\v \ []; cycle u = v @- s\ \ cycle (tl u @ [hd u]) = tl v @- s" by (auto dest: arg_cong[of _ _ stl]) @@ -304,13 +287,9 @@ subsection {* stream repeating a single element *} -definition "same x = stream_unfold (\_. x) id ()" - -lemma same_simps[simp]: "shd (same x) = x" "stl (same x) = same x" - unfolding same_def by auto - -lemma same_unfold[code]: "same x = x ## same x" - by (metis same_simps stream.collapse) +primcorec same where + "shd (same x) = x" +| "stl (same x) = same x" lemma snth_same[simp]: "same x !! n = x" unfolding same_def by (induct n) auto @@ -328,18 +307,13 @@ unfolding stream_all_def by auto lemma same_cycle: "same x = cycle [x]" - by (coinduct rule: stream.coinduct[of "\s1 s2. s1 = same x \ s2 = cycle [x]"]) auto + by coinduction auto subsection {* stream of natural numbers *} -definition "fromN n = stream_unfold id Suc n" - -lemma fromN_simps[simp]: "shd (fromN n) = n" "stl (fromN n) = fromN (Suc n)" - unfolding fromN_def by auto - -lemma fromN_unfold[code]: "fromN n = n ## fromN (Suc n)" - unfolding fromN_def by (metis id_def stream.unfold) +primcorec fromN :: "nat \ nat stream" where + "fromN n = n ## fromN (n + 1)" lemma snth_fromN[simp]: "fromN n !! m = n + m" unfolding fromN_def by (induct m arbitrary: n) auto @@ -352,12 +326,12 @@ lemma sset_fromN[simp]: "sset (fromN n) = {n ..}" (is "?L = ?R") proof safe - fix m assume "m : ?L" + fix m assume "m \ ?L" moreover { fix s assume "m \ sset s" "\n'\n. s = fromN n'" - hence "n \ m" by (induct arbitrary: n rule: sset_induct1) fastforce+ + hence "n \ m" by (induct arbitrary: n rule: sset_induct1) fastforce+ } - ultimately show "n \ m" by blast + ultimately show "n \ m" by auto next fix m assume "n \ m" thus "m \ ?L" by (metis le_iff_add snth_fromN snth_sset) qed @@ -367,16 +341,12 @@ subsection {* flatten a stream of lists *} -definition flat where - "flat \ stream_unfold (hd o shd) (\s. if tl (shd s) = [] then stl s else tl (shd s) ## stl s)" - -lemma flat_simps[simp]: +primcorec flat where "shd (flat ws) = hd (shd ws)" - "stl (flat ws) = flat (if tl (shd ws) = [] then stl ws else tl (shd ws) ## stl ws)" - unfolding flat_def by auto +| "stl (flat ws) = flat (if tl (shd ws) = [] then stl ws else tl (shd ws) ## stl ws)" lemma flat_Cons[simp, code]: "flat ((x # xs) ## ws) = x ## flat (if xs = [] then ws else xs ## ws)" - unfolding flat_def using stream.unfold[of "hd o shd" _ "(x # xs) ## ws"] by auto + by (subst flat.ctr) simp lemma flat_Stream[simp]: "xs \ [] \ flat (xs ## ws) = xs @- flat ws" by (induct xs) auto @@ -465,17 +435,13 @@ subsection {* interleave two streams *} -definition sinterleave :: "'a stream \ 'a stream \ 'a stream" where - [code del]: "sinterleave s1 s2 = - stream_unfold (\(s1, s2). shd s1) (\(s1, s2). (s2, stl s1)) (s1, s2)" - -lemma sinterleave_simps[simp]: - "shd (sinterleave s1 s2) = shd s1" "stl (sinterleave s1 s2) = sinterleave s2 (stl s1)" - unfolding sinterleave_def by auto +primcorec sinterleave where + "shd (sinterleave s1 s2) = shd s1" +| "stl (sinterleave s1 s2) = sinterleave s2 (stl s1)" lemma sinterleave_code[code]: "sinterleave (x ## s1) s2 = x ## sinterleave s2 s1" - by (metis sinterleave_simps stream.exhaust stream.sel) + by (subst sinterleave.ctr) simp lemma sinterleave_snth[simp]: "even n \ sinterleave s1 s2 !! n = s1 !! (n div 2)" @@ -507,15 +473,12 @@ subsection {* zip *} -definition "szip s1 s2 = - stream_unfold (map_pair shd shd) (map_pair stl stl) (s1, s2)" - -lemma szip_simps[simp]: - "shd (szip s1 s2) = (shd s1, shd s2)" "stl (szip s1 s2) = szip (stl s1) (stl s2)" - unfolding szip_def by auto +primcorec szip where + "shd (szip s1 s2) = (shd s1, shd s2)" +| "stl (szip s1 s2) = szip (stl s1) (stl s2)" lemma szip_unfold[code]: "szip (Stream a s1) (Stream b s2) = Stream (a, b) (szip s1 s2)" - unfolding szip_def by (subst stream.unfold) simp + by (subst szip.ctr) simp lemma snth_szip[simp]: "szip s1 s2 !! n = (s1 !! n, s2 !! n)" by (induct n arbitrary: s1 s2) auto @@ -523,35 +486,24 @@ subsection {* zip via function *} -definition "smap2 f s1 s2 = - stream_unfold (\(s1,s2). f (shd s1) (shd s2)) (map_pair stl stl) (s1, s2)" - -lemma smap2_simps[simp]: +primcorec smap2 where "shd (smap2 f s1 s2) = f (shd s1) (shd s2)" - "stl (smap2 f s1 s2) = smap2 f (stl s1) (stl s2)" - unfolding smap2_def by auto +| "stl (smap2 f s1 s2) = smap2 f (stl s1) (stl s2)" lemma smap2_unfold[code]: "smap2 f (Stream a s1) (Stream b s2) = Stream (f a b) (smap2 f s1 s2)" - unfolding smap2_def by (subst stream.unfold) simp + by (subst smap2.ctr) simp lemma smap2_szip: "smap2 f s1 s2 = smap (split f) (szip s1 s2)" - by (coinduct rule: stream.coinduct[of - "\s1 s2. \s1' s2'. s1 = smap2 f s1' s2' \ s2 = smap (split f) (szip s1' s2')"]) - fastforce+ + by (coinduction arbitrary: s1 s2) auto subsection {* iterated application of a function *} -definition siterate :: "('a \ 'a) \ 'a \ 'a stream" where - "siterate f x = x ## stream_unfold f f x" - -lemma siterate_simps[simp]: "shd (siterate f x) = x" "stl (siterate f x) = siterate f (f x)" - unfolding siterate_def by (auto intro: stream.unfold) - -lemma siterate_code[code]: "siterate f x = x ## siterate f (f x)" - by (metis siterate_def stream.unfold) +primcorec siterate where + "shd (siterate f x) = x" +| "stl (siterate f x) = siterate f (f x)" lemma stake_Suc: "stake (Suc n) s = stake n s @ [s !! n]" by (induct n arbitrary: s) auto diff -r 82d9b2701a03 -r e5853a648b59 src/HOL/BNF/Examples/TreeFI.thy --- a/src/HOL/BNF/Examples/TreeFI.thy Wed Oct 02 11:57:52 2013 +0200 +++ b/src/HOL/BNF/Examples/TreeFI.thy Wed Oct 02 13:29:04 2013 +0200 @@ -14,17 +14,10 @@ codatatype 'a treeFI = Tree (lab: 'a) (sub: "'a treeFI listF") -definition pair_fun (infixr "\" 50) where - "f \ g \ \x. (f x, g x)" - (* Tree reverse:*) -definition "trev \ treeFI_unfold lab (lrev o sub)" - -lemma trev_simps1[simp]: "lab (trev t) = lab t" - unfolding trev_def by simp - -lemma trev_simps2[simp]: "sub (trev t) = mapF trev (lrev (sub t))" - unfolding trev_def by simp +primcorec trev where + "lab (trev t) = lab t" +| "sub (trev t) = mapF trev (lrev (sub t))" lemma treeFI_coinduct: assumes *: "phi x y" @@ -33,9 +26,10 @@ lengthh (sub a) = lengthh (sub b) \ (\i < lengthh (sub a). phi (nthh (sub a) i) (nthh (sub b) i))" shows "x = y" -using * proof (coinduct rule: treeFI.coinduct) - fix t1 t2 assume "phi t1 t2" note * = step[OF this] and ** = conjunct2[OF *] - from conjunct1[OF **] conjunct2[OF **] have "relF phi (sub t1) (sub t2)" +using * proof (coinduction arbitrary: x y) + case (Eq_treeFI t1 t2) + from conjunct1[OF conjunct2[OF step[OF Eq_treeFI]]] conjunct2[OF conjunct2[OF step[OF Eq_treeFI]]] + have "relF phi (sub t1) (sub t2)" proof (induction "sub t1" "sub t2" arbitrary: t1 t2 rule: listF_induct2) case (Conss x xs y ys) note sub = Conss(2,3)[symmetric] and phi = mp[OF spec[OF Conss(4)], unfolded sub] @@ -43,10 +37,10 @@ unfolded sub, simplified] from phi[of 0] show ?case unfolding sub by (auto intro!: IH dest: phi[simplified, OF Suc_mono]) qed simp - with conjunct1[OF *] show "lab t1 = lab t2 \ relF phi (sub t1) (sub t2)" .. + with conjunct1[OF step[OF Eq_treeFI]] show ?case by simp qed lemma trev_trev: "trev (trev tr) = tr" - by (rule treeFI_coinduct[of "%a b. trev (trev b) = a"]) auto + by (coinduction arbitrary: tr rule: treeFI_coinduct) auto end diff -r 82d9b2701a03 -r e5853a648b59 src/HOL/BNF/Examples/TreeFsetI.thy --- a/src/HOL/BNF/Examples/TreeFsetI.thy Wed Oct 02 11:57:52 2013 +0200 +++ b/src/HOL/BNF/Examples/TreeFsetI.thy Wed Oct 02 13:29:04 2013 +0200 @@ -16,22 +16,12 @@ codatatype 'a treeFsetI = Tree (lab: 'a) (sub: "'a treeFsetI fset") -definition pair_fun (infixr "\" 50) where - "f \ g \ \x. (f x, g x)" - (* tree map (contrived example): *) -definition tmap where -"tmap f = treeFsetI_unfold (f o lab) sub" - -lemma tmap_simps[simp]: -"lab (tmap f t) = f (lab t)" +primcorec tmap where +"lab (tmap f t) = f (lab t)" | "sub (tmap f t) = fimage (tmap f) (sub t)" -unfolding tmap_def treeFsetI.sel_unfold by simp+ lemma "tmap (f o g) x = tmap f (tmap g x)" -apply (rule treeFsetI.coinduct[of "%x1 x2. \x. x1 = tmap (f o g) x \ x2 = tmap f (tmap g x)"]) -apply auto -apply (unfold fset_rel_alt) -by auto + by (coinduction arbitrary: x) (auto simp: fset_rel_alt) end