# HG changeset patch # User wenzelm # Date 1389353405 -3600 # Node ID 2a010ef82fd74dfb0ba86b2f655ebd43618b5745 # Parent e60428f432bcc75fdba79d13024503b92c206613# Parent a8af7a9c38d1563f5ebf2cb67aef63f3c936275c merged diff -r a8af7a9c38d1 -r 2a010ef82fd7 src/HOL/BNF/BNF_Def.thy --- a/src/HOL/BNF/BNF_Def.thy Fri Jan 10 12:29:25 2014 +0100 +++ b/src/HOL/BNF/BNF_Def.thy Fri Jan 10 12:30:05 2014 +0100 @@ -150,6 +150,9 @@ lemma convol_image_vimage2p: " ` Collect (split (vimage2p f g R)) \ Collect (split R)" unfolding vimage2p_def convol_def by auto +lemma vimage2p_Grp: "vimage2p f g P = Grp UNIV f OO P OO (Grp UNIV g)\\" + unfolding vimage2p_def Grp_def by auto + (*FIXME: duplicates lemma from Record.thy*) lemma o_eq_dest_lhs: "a o b = c \ a (b v) = c v" by clarsimp diff -r a8af7a9c38d1 -r 2a010ef82fd7 src/HOL/BNF/Examples/Stream_Processor.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/BNF/Examples/Stream_Processor.thy Fri Jan 10 12:30:05 2014 +0100 @@ -0,0 +1,187 @@ +(* Title: HOL/BNF/Examples/Stream_Processor.thy + Author: Dmitriy Traytel, TU Muenchen + Author: Andrei Popescu, TU Muenchen + Copyright 2014 + +Stream processors---a syntactic representation of continuous functions on streams +*) + +header {* Stream Processors *} + +theory Stream_Processor +imports Stream +begin + +section {* Continuous Functions on Streams *} + +datatype_new ('a, 'b, 'c) sp\<^sub>\ = Get "'a \ ('a, 'b, 'c) sp\<^sub>\" | Put "'b" "'c" +codatatype ('a, 'b) sp\<^sub>\ = In (out: "('a, 'b, ('a, 'b) sp\<^sub>\) sp\<^sub>\") + +primrec_new run\<^sub>\ :: "('a, 'b, 'c) sp\<^sub>\ \ 'a stream \ ('b \ 'c) \ 'a stream" where + "run\<^sub>\ (Get f) s = run\<^sub>\ (f (shd s)) (stl s)" +| "run\<^sub>\ (Put b sp) s = ((b, sp), s)" + +primcorec run\<^sub>\ :: "('a, 'b) sp\<^sub>\ \ 'a stream \ 'b stream" where + "run\<^sub>\ sp s = (let ((h, sp), s) = run\<^sub>\ (out sp) s in h ## run\<^sub>\ sp s)" + +primcorec copy :: "('a, 'a) sp\<^sub>\" where + "copy = In (Get (\a. Put a copy))" + +lemma run\<^sub>\_copy: "run\<^sub>\ copy s = s" + by (coinduction arbitrary: s) simp + +text {* +To use the function package for the definition of composition the +wellfoundedness of the subtree relation needs to be proved first. +*} + +definition "sub \ {(f a, Get f) | a f. True}" + +lemma subI[intro]: "(f a, Get f) \ sub" + unfolding sub_def by blast + +lemma wf_sub[simp, intro]: "wf sub" +proof (rule wfUNIVI) + fix P :: "('a, 'b, 'c) sp\<^sub>\ \ bool" and x + assume "\x. (\y. (y, x) \ sub \ P y) \ P x" + hence I: "\x. (\y. (\a f. y = f a \ x = Get f) \ P y) \ P x" unfolding sub_def by blast + show "P x" by (induct x) (auto intro: I) +qed + +function + sp\<^sub>\_comp :: "('a, 'b, 'c) sp\<^sub>\ \ ('d, 'a, ('d, 'a) sp\<^sub>\) sp\<^sub>\ \ ('d, 'b, 'c \ ('d, 'a) sp\<^sub>\) sp\<^sub>\" + (infixl "o\<^sub>\" 65) +where + "Put b sp o\<^sub>\ fsp = Put b (sp, In fsp)" +| "Get f o\<^sub>\ Put b sp = f b o\<^sub>\ out sp" +| "Get f o\<^sub>\ Get g = Get (\a. Get f o\<^sub>\ g a)" +by pat_completeness auto +termination by (relation "lex_prod sub sub") auto + +primcorec sp\<^sub>\_comp (infixl "o\<^sub>\" 65) where + "out (sp o\<^sub>\ sp') = map_sp\<^sub>\ id (\(sp, sp'). sp o\<^sub>\ sp') (out sp o\<^sub>\ out sp')" + +lemma run\<^sub>\_sp\<^sub>\_comp: "run\<^sub>\ (sp o\<^sub>\ sp') = run\<^sub>\ sp o run\<^sub>\ sp'" +proof (rule ext, unfold o_apply) + fix s + show "run\<^sub>\ (sp o\<^sub>\ sp') s = run\<^sub>\ sp (run\<^sub>\ sp' s)" + proof (coinduction arbitrary: sp sp' s) + case Eq_stream + show ?case + proof (induct "out sp" "out sp'" arbitrary: sp sp' s rule: sp\<^sub>\_comp.induct) + case (1 b sp'') + show ?case by (auto simp add: 1[symmetric]) + next + case (2 f b sp'') + from 2(1)[of "In (f b)" sp''] show ?case by (simp add: 2(2,3)[symmetric]) + next + case (3 f h) + from 3(1)[of _ "shd s" "In (h (shd s))", OF 3(2)] show ?case by (simp add: 3(2,3)[symmetric]) + qed + qed +qed + +text {* Alternative definition of composition using primrec_new instead of function *} + +primrec_new sp\<^sub>\_comp2R where + "sp\<^sub>\_comp2R f (Put b sp) = f b (out sp)" +| "sp\<^sub>\_comp2R f (Get h) = Get (sp\<^sub>\_comp2R f o h)" + +primrec_new sp\<^sub>\_comp2 (infixl "o\<^sup>*\<^sub>\" 65) where + "Put b sp o\<^sup>*\<^sub>\ fsp = Put b (sp, In fsp)" +| "Get f o\<^sup>*\<^sub>\ fsp = sp\<^sub>\_comp2R (op o\<^sup>*\<^sub>\ o f) fsp" + +primcorec sp\<^sub>\_comp2 (infixl "o\<^sup>*\<^sub>\" 65) where + "out (sp o\<^sup>*\<^sub>\ sp') = map_sp\<^sub>\ id (\(sp, sp'). sp o\<^sup>*\<^sub>\ sp') (out sp o\<^sup>*\<^sub>\ out sp')" + +lemma run\<^sub>\_sp\<^sub>\_comp2: "run\<^sub>\ (sp o\<^sup>*\<^sub>\ sp') = run\<^sub>\ sp o run\<^sub>\ sp'" +proof (rule ext, unfold o_apply) + fix s + show "run\<^sub>\ (sp o\<^sup>*\<^sub>\ sp') s = run\<^sub>\ sp (run\<^sub>\ sp' s)" + proof (coinduction arbitrary: sp sp' s) + case Eq_stream + show ?case + proof (induct "out sp" arbitrary: sp sp' s) + case (Put b sp'') + show ?case by (auto simp add: Put[symmetric]) + next + case (Get f) + then show ?case + proof (induct "out sp'" arbitrary: sp sp' s) + case (Put b sp'') + from Put(2)[of "In (f b)" sp''] show ?case by (simp add: Put(1,3)[symmetric]) + next + case (Get h) + from Get(1)[OF _ Get(3,4), of "In (h (shd s))"] show ?case by (simp add: Get(2,4)[symmetric]) + qed + qed + qed +qed + +text {* The two definitions are equivalent *} + +lemma sp\<^sub>\_comp_sp\<^sub>\_comp2[simp]: "sp o\<^sub>\ sp' = sp o\<^sup>*\<^sub>\ sp'" + by (induct sp sp' rule: sp\<^sub>\_comp.induct) auto + +(*will be provided by the package*) +lemma sp\<^sub>\_rel_map_map[unfolded vimage2p_def, simp]: + "rel_sp\<^sub>\ R1 R2 (map_sp\<^sub>\ f1 f2 sp) (map_sp\<^sub>\ g1 g2 sp') = + rel_sp\<^sub>\ (BNF_Def.vimage2p f1 g1 R1) (BNF_Def.vimage2p f2 g2 R2) sp sp'" +by (tactic {* + let val ks = 1 upto 2; + in + BNF_Tactics.unfold_thms_tac @{context} + @{thms sp\<^sub>\.rel_compp sp\<^sub>\.rel_conversep sp\<^sub>\.rel_Grp vimage2p_Grp} THEN + HEADGOAL (EVERY' [rtac iffI, rtac @{thm relcomppI}, rtac @{thm GrpI}, rtac refl, rtac CollectI, + BNF_Util.CONJ_WRAP' (K (rtac @{thm subset_UNIV})) ks, rtac @{thm relcomppI}, atac, + rtac @{thm conversepI}, rtac @{thm GrpI}, rtac refl, rtac CollectI, + BNF_Util.CONJ_WRAP' (K (rtac @{thm subset_UNIV})) ks, + REPEAT_DETERM o eresolve_tac @{thms relcomppE conversepE GrpE}, + hyp_subst_tac @{context}, atac]) + end +*}) + +lemma sp\<^sub>\_rel_self: "\op = \ R1; op = \ R2\ \ rel_sp\<^sub>\ R1 R2 x x" + by (erule (1) predicate2D[OF sp\<^sub>\.rel_mono]) (simp only: sp\<^sub>\.rel_eq) + +lemma sp\<^sub>\_comp_sp\<^sub>\_comp2: "sp o\<^sub>\ sp' = sp o\<^sup>*\<^sub>\ sp'" + by (coinduction arbitrary: sp sp') (auto intro!: sp\<^sub>\_rel_self) + + +section {* Generalization to an Arbitrary BNF as Codomain *} + +bnf_decl ('a, 'b) F (map: F) + +definition \ :: "('p,'a) F * 'b \ ('p,'a * 'b) F" where + "\ xb = F id a. (snd xb)> (fst xb)" + +(* The strength laws for \: *) +lemma \_natural: "F id (map_pair f g) o \ = \ o map_pair (F id f) g" + unfolding \_def F.map_comp o_def id_apply convol_def map_pair_def split_beta fst_conv snd_conv .. + +definition assl :: "'a * ('b * 'c) \ ('a * 'b) * 'c" where + "assl abc = ((fst abc, fst (snd abc)), snd (snd abc))" + +lemma \_rid: "F id fst o \ = fst" + unfolding \_def F.map_comp F.map_id o_def id_apply convol_def fst_conv sym[OF id_def] .. + +lemma \_assl: "F id assl o \ = \ o map_pair \ id o assl" + unfolding assl_def \_def F.map_comp o_def id_apply convol_def map_pair_def split fst_conv snd_conv .. + +datatype_new ('a, 'b, 'c) spF\<^sub>\ = GetF "'a \ ('a, 'b, 'c) spF\<^sub>\" | PutF "('b,'c) F" +codatatype ('a, 'b) spF\<^sub>\ = InF (outF: "('a, 'b, ('a, 'b) spF\<^sub>\) spF\<^sub>\") + +codatatype 'b JF = Ctor (dtor: "('b, 'b JF) F") + +(* Definition of run for an arbitrary final coalgebra as codomain: *) + +primrec_new + runF\<^sub>\ :: "('a, 'b, ('a, 'b) spF\<^sub>\) spF\<^sub>\ \ 'a stream \ (('b, ('a, 'b) spF\<^sub>\) F) \ 'a stream" +where + "runF\<^sub>\ (GetF f) s = (runF\<^sub>\ o f) (shd s) (stl s)" +| "runF\<^sub>\ (PutF x) s = (x, s)" + +primcorec runF\<^sub>\ :: "('a, 'b) spF\<^sub>\ \ 'a stream \ 'b JF" where + "runF\<^sub>\ sp s = (let (x, s) = runF\<^sub>\ (outF sp) s in Ctor (F id (\ sp. runF\<^sub>\ sp s) x))" + +end diff -r a8af7a9c38d1 -r 2a010ef82fd7 src/HOL/BNF/Tools/bnf_decl.ML --- a/src/HOL/BNF/Tools/bnf_decl.ML Fri Jan 10 12:29:25 2014 +0100 +++ b/src/HOL/BNF/Tools/bnf_decl.ML Fri Jan 10 12:30:05 2014 +0100 @@ -64,18 +64,19 @@ fun mk_wits_tac set_maps = K (TRYALL Goal.conjunction_tac) THEN' the triv_tac_opt set_maps; val wit_goals = map Logic.mk_conjunction_balanced wit_goalss; - fun mk_wit_thms set_maps = - Goal.prove_sorry lthy [] [] (Logic.mk_conjunction_balanced wit_goals) (mk_wits_tac set_maps) - |> Conjunction.elim_balanced (length wit_goals) - |> map2 (Conjunction.elim_balanced o length) wit_goalss - |> map (map (Thm.close_derivation o Thm.forall_elim_vars 0)); val ((_, [thms]), (lthy_old, lthy)) = Local_Theory.background_theory_result (Specification.axiomatization [] [((mk_b "axioms" Binding.empty, []), goals)]) lthy ||> `Local_Theory.restore; + + fun mk_wit_thms set_maps = + Goal.prove_sorry lthy [] [] (Logic.mk_conjunction_balanced wit_goals) (mk_wits_tac set_maps) + |> Conjunction.elim_balanced (length wit_goals) + |> map2 (Conjunction.elim_balanced o length) wit_goalss + |> map (map (Thm.close_derivation o Thm.forall_elim_vars 0)); val phi = Proof_Context.export_morphism lthy_old lthy; in - BNF_Def.register_bnf key (after_qed mk_wit_thms (map single (Morphism.fact phi thms)) lthy) + BNF_Def.register_bnf key (after_qed mk_wit_thms (map single (Morphism.fact phi thms)) lthy) end; val bnf_decl = prepare_decl (K I) (K I); diff -r a8af7a9c38d1 -r 2a010ef82fd7 src/HOL/ROOT --- a/src/HOL/ROOT Fri Jan 10 12:29:25 2014 +0100 +++ b/src/HOL/ROOT Fri Jan 10 12:30:05 2014 +0100 @@ -731,6 +731,7 @@ "Derivation_Trees/Gram_Lang" "Derivation_Trees/Parallel" Koenig + Stream_Processor theories [condition = ISABELLE_FULL_TEST] Misc_Codatatype Misc_Datatype