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 |