src/HOL/Imperative_HOL/Heap_Monad.thy
changeset 37772 026ed2fc15d4
parent 37771 1bec64044b5e
child 37787 30dc3abf4a58
equal deleted inserted replaced
37771:1bec64044b5e 37772:026ed2fc15d4
   473     where y: "execute (f x) h = Some (y, h)" by auto
   473     where y: "execute (f x) h = Some (y, h)" by auto
   474   moreover from Cons.prems Cons.hyps have "execute (fold_map f xs) h =
   474   moreover from Cons.prems Cons.hyps have "execute (fold_map f xs) h =
   475     Some (map (\<lambda>x. fst (the (execute (f x) h))) xs, h)" by auto
   475     Some (map (\<lambda>x. fst (the (execute (f x) h))) xs, h)" by auto
   476   ultimately show ?case by (simp, simp only: execute_bind(1), simp)
   476   ultimately show ?case by (simp, simp only: execute_bind(1), simp)
   477 qed
   477 qed
   478 
       
   479 
       
   480 subsubsection {* A monadic combinator for simple recursive functions *}
       
   481 
       
   482 text {* Using a locale to fix arguments f and g of MREC *}
       
   483 
       
   484 locale mrec =
       
   485   fixes f :: "'a \<Rightarrow> ('b + 'a) Heap"
       
   486   and g :: "'a \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'b Heap"
       
   487 begin
       
   488 
       
   489 function (default "\<lambda>(x, h). None") mrec :: "'a \<Rightarrow> heap \<Rightarrow> ('b \<times> heap) option" where
       
   490   "mrec x h = (case execute (f x) h of
       
   491      Some (Inl r, h') \<Rightarrow> Some (r, h')
       
   492    | Some (Inr s, h') \<Rightarrow> (case mrec s h' of
       
   493              Some (z, h'') \<Rightarrow> execute (g x s z) h''
       
   494            | None \<Rightarrow> None)
       
   495    | None \<Rightarrow> None)"
       
   496 by auto
       
   497 
       
   498 lemma graph_implies_dom:
       
   499   "mrec_graph x y \<Longrightarrow> mrec_dom x"
       
   500 apply (induct rule:mrec_graph.induct) 
       
   501 apply (rule accpI)
       
   502 apply (erule mrec_rel.cases)
       
   503 by simp
       
   504 
       
   505 lemma mrec_default: "\<not> mrec_dom (x, h) \<Longrightarrow> mrec x h = None"
       
   506   unfolding mrec_def 
       
   507   by (rule fundef_default_value[OF mrec_sumC_def graph_implies_dom, of _ _ "(x, h)", simplified])
       
   508 
       
   509 lemma mrec_di_reverse: 
       
   510   assumes "\<not> mrec_dom (x, h)"
       
   511   shows "
       
   512    (case execute (f x) h of
       
   513      Some (Inl r, h') \<Rightarrow> False
       
   514    | Some (Inr s, h') \<Rightarrow> \<not> mrec_dom (s, h')
       
   515    | None \<Rightarrow> False
       
   516    )" 
       
   517 using assms apply (auto split: option.split sum.split)
       
   518 apply (rule ccontr)
       
   519 apply (erule notE, rule accpI, elim mrec_rel.cases, auto)+
       
   520 done
       
   521 
       
   522 lemma mrec_rule:
       
   523   "mrec x h = 
       
   524    (case execute (f x) h of
       
   525      Some (Inl r, h') \<Rightarrow> Some (r, h')
       
   526    | Some (Inr s, h') \<Rightarrow> 
       
   527           (case mrec s h' of
       
   528              Some (z, h'') \<Rightarrow> execute (g x s z) h''
       
   529            | None \<Rightarrow> None)
       
   530    | None \<Rightarrow> None
       
   531    )"
       
   532 apply (cases "mrec_dom (x,h)", simp)
       
   533 apply (frule mrec_default)
       
   534 apply (frule mrec_di_reverse, simp)
       
   535 by (auto split: sum.split option.split simp: mrec_default)
       
   536 
       
   537 definition
       
   538   "MREC x = Heap (mrec x)"
       
   539 
       
   540 lemma MREC_rule:
       
   541   "MREC x = 
       
   542   (do y \<leftarrow> f x;
       
   543                 (case y of 
       
   544                 Inl r \<Rightarrow> return r
       
   545               | Inr s \<Rightarrow> 
       
   546                 do z \<leftarrow> MREC s ;
       
   547                    g x s z
       
   548                 done) done)"
       
   549   unfolding MREC_def
       
   550   unfolding bind_def return_def
       
   551   apply simp
       
   552   apply (rule ext)
       
   553   apply (unfold mrec_rule[of x])
       
   554   by (auto split: option.splits prod.splits sum.splits)
       
   555 
       
   556 lemma MREC_pinduct:
       
   557   assumes "execute (MREC x) h = Some (r, h')"
       
   558   assumes non_rec_case: "\<And> x h h' r. execute (f x) h = Some (Inl r, h') \<Longrightarrow> P x h h' r"
       
   559   assumes rec_case: "\<And> x h h1 h2 h' s z r. execute (f x) h = Some (Inr s, h1) \<Longrightarrow> execute (MREC s) h1 = Some (z, h2) \<Longrightarrow> P s h1 h2 z
       
   560     \<Longrightarrow> execute (g x s z) h2 = Some (r, h') \<Longrightarrow> P x h h' r"
       
   561   shows "P x h h' r"
       
   562 proof -
       
   563   from assms(1) have mrec: "mrec x h = Some (r, h')"
       
   564     unfolding MREC_def execute.simps .
       
   565   from mrec have dom: "mrec_dom (x, h)"
       
   566     apply -
       
   567     apply (rule ccontr)
       
   568     apply (drule mrec_default) by auto
       
   569   from mrec have h'_r: "h' = snd (the (mrec x h))" "r = fst (the (mrec x h))"
       
   570     by auto
       
   571   from mrec have "P x h (snd (the (mrec x h))) (fst (the (mrec x h)))"
       
   572   proof (induct arbitrary: r h' rule: mrec.pinduct[OF dom])
       
   573     case (1 x h)
       
   574     obtain rr h' where "the (mrec x h) = (rr, h')" by fastsimp
       
   575     show ?case
       
   576     proof (cases "execute (f x) h")
       
   577       case (Some result)
       
   578       then obtain a h1 where exec_f: "execute (f x) h = Some (a, h1)" by fastsimp
       
   579       note Inl' = this
       
   580       show ?thesis
       
   581       proof (cases a)
       
   582         case (Inl aa)
       
   583         from this Inl' 1(1) exec_f mrec non_rec_case show ?thesis
       
   584           by auto
       
   585       next
       
   586         case (Inr b)
       
   587         note Inr' = this
       
   588         show ?thesis
       
   589         proof (cases "mrec b h1")
       
   590           case (Some result)
       
   591           then obtain aaa h2 where mrec_rec: "mrec b h1 = Some (aaa, h2)" by fastsimp
       
   592           moreover from this have "P b h1 (snd (the (mrec b h1))) (fst (the (mrec b h1)))"
       
   593             apply (intro 1(2))
       
   594             apply (auto simp add: Inr Inl')
       
   595             done
       
   596           moreover note mrec mrec_rec exec_f Inl' Inr' 1(1) 1(3)
       
   597           ultimately show ?thesis
       
   598             apply auto
       
   599             apply (rule rec_case)
       
   600             apply auto
       
   601             unfolding MREC_def by auto
       
   602         next
       
   603           case None
       
   604           from this 1(1) exec_f mrec Inr' 1(3) show ?thesis by auto
       
   605         qed
       
   606       qed
       
   607     next
       
   608       case None
       
   609       from this 1(1) mrec 1(3) show ?thesis by simp
       
   610     qed
       
   611   qed
       
   612   from this h'_r show ?thesis by simp
       
   613 qed
       
   614 
       
   615 end
       
   616 
       
   617 text {* Providing global versions of the constant and the theorems *}
       
   618 
       
   619 abbreviation "MREC == mrec.MREC"
       
   620 lemmas MREC_rule = mrec.MREC_rule
       
   621 lemmas MREC_pinduct = mrec.MREC_pinduct
       
   622 
       
   623 
   478 
   624 subsection {* Code generator setup *}
   479 subsection {* Code generator setup *}
   625 
   480 
   626 subsubsection {* Logical intermediate layer *}
   481 subsubsection {* Logical intermediate layer *}
   627 
   482