# HG changeset patch # User traytel # Date 1377007858 -7200 # Node ID c0217c4a6b2dae45d2bcb730c1e49155e862a747 # Parent 45a7bfd99b45ec4fbb06edfa68e0fb94a29628b0 tuned example diff -r 45a7bfd99b45 -r c0217c4a6b2d src/HOL/BNF/Examples/Process.thy --- a/src/HOL/BNF/Examples/Process.thy Tue Aug 20 14:39:55 2013 +0200 +++ b/src/HOL/BNF/Examples/Process.thy Tue Aug 20 16:10:58 2013 +0200 @@ -8,7 +8,7 @@ header {* Processes *} theory Process -imports "../BNF" +imports Stream begin codatatype 'a process = @@ -38,81 +38,31 @@ subsection{* Coinduction *} theorem process_coind[elim, consumes 1, case_names iss Action Choice, induct pred: "HOL.eq"]: -assumes phi: "\ p p'" and -iss: "\p p'. \ p p' \ (isAction p \ isAction p') \ (isChoice p \ isChoice p')" and -Act: "\ a a' p p'. \ (Action a p) (Action a' p') \ a = a' \ \ p p'" and -Ch: "\ p q p' q'. \ (Choice p q) (Choice p' q') \ \ p p' \ \ q q'" -shows "p = p'" -proof(intro mp[OF process.dtor_coinduct, of \, OF _ phi], clarify) - fix p p' assume \: "\ p p'" - show "pre_process_rel (op =) \ (process_dtor p) (process_dtor p')" - proof(cases rule: process.exhaust[of p]) - case (Action a q) note p = Action - hence "isAction p'" using iss[OF \] by (cases rule: process.exhaust[of p'], auto) - then obtain a' q' where p': "p' = Action a' q'" by (cases rule: process.exhaust[of p'], auto) - have 0: "a = a' \ \ q q'" using Act[OF \[unfolded p p']] . - have dtor: "process_dtor p = Inl (a,q)" "process_dtor p' = Inl (a',q')" - unfolding p p' Action_def process.dtor_ctor by simp_all - show ?thesis using 0 unfolding dtor by simp - next - case (Choice p1 p2) note p = Choice - hence "isChoice p'" using iss[OF \] by (cases rule: process.exhaust[of p'], auto) - then obtain p1' p2' where p': "p' = Choice p1' p2'" - by (cases rule: process.exhaust[of p'], auto) - have 0: "\ p1 p1' \ \ p2 p2'" using Ch[OF \[unfolded p p']] . - have dtor: "process_dtor p = Inr (p1,p2)" "process_dtor p' = Inr (p1',p2')" - unfolding p p' Choice_def process.dtor_ctor by simp_all - show ?thesis using 0 unfolding dtor by simp - qed -qed + assumes phi: "\ p p'" and + iss: "\p p'. \ p p' \ (isAction p \ isAction p') \ (isChoice p \ isChoice p')" and + Act: "\ a a' p p'. \ (Action a p) (Action a' p') \ a = a' \ \ p p'" and + Ch: "\ p q p' q'. \ (Choice p q) (Choice p' q') \ \ p p' \ \ q q'" + shows "p = p'" + using assms + by (coinduct rule: process.coinduct) (metis process.collapse(1,2) process.discs(3)) (* Stronger coinduction, up to equality: *) theorem process_strong_coind[elim, consumes 1, case_names iss Action Choice]: -assumes phi: "\ p p'" and -iss: "\p p'. \ p p' \ (isAction p \ isAction p') \ (isChoice p \ isChoice p')" and -Act: "\ a a' p p'. \ (Action a p) (Action a' p') \ a = a' \ (\ p p' \ p = p')" and -Ch: "\ p q p' q'. \ (Choice p q) (Choice p' q') \ (\ p p' \ p = p') \ (\ q q' \ q = q')" -shows "p = p'" -proof(intro mp[OF process.dtor_strong_coinduct, of \, OF _ phi], clarify) - fix p p' assume \: "\ p p'" - show "pre_process_rel (op =) (\a b. \ a b \ a = b) (process_dtor p) (process_dtor p')" - proof(cases rule: process.exhaust[of p]) - case (Action a q) note p = Action - hence "isAction p'" using iss[OF \] by (cases rule: process.exhaust[of p'], auto) - then obtain a' q' where p': "p' = Action a' q'" by (cases rule: process.exhaust[of p'], auto) - have 0: "a = a' \ (\ q q' \ q = q')" using Act[OF \[unfolded p p']] . - have dtor: "process_dtor p = Inl (a,q)" "process_dtor p' = Inl (a',q')" - unfolding p p' Action_def process.dtor_ctor by simp_all - show ?thesis using 0 unfolding dtor by simp - next - case (Choice p1 p2) note p = Choice - hence "isChoice p'" using iss[OF \] by (cases rule: process.exhaust[of p'], auto) - then obtain p1' p2' where p': "p' = Choice p1' p2'" - by (cases rule: process.exhaust[of p'], auto) - have 0: "(\ p1 p1' \ p1 = p1') \ (\ p2 p2' \ p2 = p2')" using Ch[OF \[unfolded p p']] . - have dtor: "process_dtor p = Inr (p1,p2)" "process_dtor p' = Inr (p1',p2')" - unfolding p p' Choice_def process.dtor_ctor by simp_all - show ?thesis using 0 unfolding dtor by simp - qed -qed + assumes phi: "\ p p'" and + iss: "\p p'. \ p p' \ (isAction p \ isAction p') \ (isChoice p \ isChoice p')" and + Act: "\ a a' p p'. \ (Action a p) (Action a' p') \ a = a' \ (\ p p' \ p = p')" and + Ch: "\ p q p' q'. \ (Choice p q) (Choice p' q') \ (\ p p' \ p = p') \ (\ q q' \ q = q')" + shows "p = p'" + using assms + by (coinduct rule: process.strong_coinduct) (metis process.collapse(1,2) process.discs(3)) subsection {* Coiteration (unfold) *} section{* Coinductive definition of the notion of trace *} - -(* Say we have a type of streams: *) - -typedecl 'a stream - -consts Ccons :: "'a \ 'a stream \ 'a stream" - -(* Use the existing coinductive package (distinct from our -new codatatype package, but highly compatible with it): *) - coinductive trace where -"trace p as \ trace (Action a p) (Ccons a as)" +"trace p as \ trace (Action a p) (a ## as)" | "trace p as \ trace q as \ trace (Choice p q) as"