662 | "Lmerge [] ys = ys" |
662 | "Lmerge [] ys = ys" |
663 | "Lmerge xs [] = xs" |
663 | "Lmerge xs [] = xs" |
664 |
664 |
665 subsection {* Definition of merge function *} |
665 subsection {* Definition of merge function *} |
666 |
666 |
667 definition merge' :: "(('a::{heap, ord}) node ref * ('a::{heap, ord})) * ('a::{heap, ord}) node ref * ('a::{heap, ord}) node ref \<Rightarrow> ('a::{heap, ord}) node ref Heap" |
667 partial_function (heap) merge :: "('a::{heap, ord}) node ref \<Rightarrow> 'a node ref \<Rightarrow> 'a node ref Heap" |
668 where |
668 where |
669 "merge' = MREC (\<lambda>(_, p, q). do { v \<leftarrow> !p; w \<leftarrow> !q; |
669 [code]: "merge p q = (do { v \<leftarrow> !p; w \<leftarrow> !q; |
670 (case v of Empty \<Rightarrow> return (Inl q) |
670 (case v of Empty \<Rightarrow> return q |
671 | Node valp np \<Rightarrow> |
671 | Node valp np \<Rightarrow> |
672 (case w of Empty \<Rightarrow> return (Inl p) |
672 (case w of Empty \<Rightarrow> return p |
673 | Node valq nq \<Rightarrow> |
673 | Node valq nq \<Rightarrow> |
674 if (valp \<le> valq) then |
674 if (valp \<le> valq) then do { |
675 return (Inr ((p, valp), np, q)) |
675 npq \<leftarrow> merge np q; |
676 else |
676 p := Node valp npq; |
677 return (Inr ((q, valq), p, nq)))) }) |
677 return p } |
678 (\<lambda> _ ((n, v), _, _) r. do { n := Node v r; return n })" |
678 else do { |
679 |
679 pnq \<leftarrow> merge p nq; |
680 definition merge where "merge p q = merge' (undefined, p, q)" |
680 q := Node valq pnq; |
|
681 return q }))})" |
|
682 |
681 |
683 |
682 lemma if_return: "(if P then return x else return y) = return (if P then x else y)" |
684 lemma if_return: "(if P then return x else return y) = return (if P then x else y)" |
683 by auto |
685 by auto |
684 |
686 |
685 lemma if_distrib_App: "(if P then f else g) x = (if P then f x else g x)" |
687 lemma if_distrib_App: "(if P then f else g) x = (if P then f x else g x)" |
690 |
692 |
691 |
693 |
692 |
694 |
693 lemma sum_distrib: "sum_case fl fr (case x of Empty \<Rightarrow> y | Node v n \<Rightarrow> (z v n)) = (case x of Empty \<Rightarrow> sum_case fl fr y | Node v n \<Rightarrow> sum_case fl fr (z v n))" |
695 lemma sum_distrib: "sum_case fl fr (case x of Empty \<Rightarrow> y | Node v n \<Rightarrow> (z v n)) = (case x of Empty \<Rightarrow> sum_case fl fr y | Node v n \<Rightarrow> sum_case fl fr (z v n))" |
694 by (cases x) auto |
696 by (cases x) auto |
695 |
|
696 lemma merge: "merge' (x, p, q) = merge p q" |
|
697 unfolding merge'_def merge_def |
|
698 apply (simp add: MREC_rule) done |
|
699 term "Ref.change" |
|
700 lemma merge_simps [code]: |
|
701 shows "merge p q = |
|
702 do { v \<leftarrow> !p; |
|
703 w \<leftarrow> !q; |
|
704 (case v of node.Empty \<Rightarrow> return q |
|
705 | Node valp np \<Rightarrow> |
|
706 case w of node.Empty \<Rightarrow> return p |
|
707 | Node valq nq \<Rightarrow> |
|
708 if valp \<le> valq then do { r \<leftarrow> merge np q; |
|
709 p := (Node valp r); |
|
710 return p |
|
711 } |
|
712 else do { r \<leftarrow> merge p nq; |
|
713 q := (Node valq r); |
|
714 return q |
|
715 }) |
|
716 }" |
|
717 proof - |
|
718 {fix v x y |
|
719 have case_return: "(case v of Empty \<Rightarrow> return x | Node v n \<Rightarrow> return (y v n)) = return (case v of Empty \<Rightarrow> x | Node v n \<Rightarrow> y v n)" by (cases v) auto |
|
720 } note case_return = this |
|
721 show ?thesis |
|
722 unfolding merge_def[of p q] merge'_def |
|
723 apply (simp add: MREC_rule[of _ _ "(undefined, p, q)"]) |
|
724 unfolding bind_bind return_bind |
|
725 unfolding merge'_def[symmetric] |
|
726 unfolding if_return case_return bind_bind return_bind sum_distrib sum.cases |
|
727 unfolding if_distrib[symmetric, where f="Inr"] |
|
728 unfolding sum.cases |
|
729 unfolding if_distrib |
|
730 unfolding split_beta fst_conv snd_conv |
|
731 unfolding if_distrib_App redundant_if merge |
|
732 .. |
|
733 qed |
|
734 |
697 |
735 subsection {* Induction refinement by applying the abstraction function to our induct rule *} |
698 subsection {* Induction refinement by applying the abstraction function to our induct rule *} |
736 |
699 |
737 text {* From our original induction rule Lmerge.induct, we derive a new rule with our list_of' predicate *} |
700 text {* From our original induction rule Lmerge.induct, we derive a new rule with our list_of' predicate *} |
738 |
701 |
798 shows "P p q h h' r xs ys" |
761 shows "P p q h h' r xs ys" |
799 using assms(3) |
762 using assms(3) |
800 proof (induct arbitrary: h' r rule: merge_induct2[OF assms(1) assms(2)]) |
763 proof (induct arbitrary: h' r rule: merge_induct2[OF assms(1) assms(2)]) |
801 case (1 ys p q) |
764 case (1 ys p q) |
802 from 1(3-4) have "h = h' \<and> r = q" |
765 from 1(3-4) have "h = h' \<and> r = q" |
803 unfolding merge_simps[of p q] |
766 unfolding merge.simps[of p q] |
804 by (auto elim!: effect_lookupE effect_bindE effect_returnE) |
767 by (auto elim!: effect_lookupE effect_bindE effect_returnE) |
805 with assms(4)[OF 1(1) 1(2) 1(3)] show ?case by simp |
768 with assms(4)[OF 1(1) 1(2) 1(3)] show ?case by simp |
806 next |
769 next |
807 case (2 x xs' p q pn) |
770 case (2 x xs' p q pn) |
808 from 2(3-5) have "h = h' \<and> r = p" |
771 from 2(3-5) have "h = h' \<and> r = p" |
809 unfolding merge_simps[of p q] |
772 unfolding merge.simps[of p q] |
810 by (auto elim!: effect_lookupE effect_bindE effect_returnE) |
773 by (auto elim!: effect_lookupE effect_bindE effect_returnE) |
811 with assms(5)[OF 2(1-4)] show ?case by simp |
774 with assms(5)[OF 2(1-4)] show ?case by simp |
812 next |
775 next |
813 case (3 x xs' y ys' p q pn qn) |
776 case (3 x xs' y ys' p q pn qn) |
814 from 3(3-5) 3(7) obtain h1 r1 where |
777 from 3(3-5) 3(7) obtain h1 r1 where |
815 1: "effect (merge pn q) h h1 r1" |
778 1: "effect (merge pn q) h h1 r1" |
816 and 2: "h' = Ref.set p (Node x r1) h1 \<and> r = p" |
779 and 2: "h' = Ref.set p (Node x r1) h1 \<and> r = p" |
817 unfolding merge_simps[of p q] |
780 unfolding merge.simps[of p q] |
818 by (auto elim!: effect_lookupE effect_bindE effect_returnE effect_ifE effect_updateE) |
781 by (auto elim!: effect_lookupE effect_bindE effect_returnE effect_ifE effect_updateE) |
819 from 3(6)[OF 1] assms(6) [OF 3(1-5)] 1 2 show ?case by simp |
782 from 3(6)[OF 1] assms(6) [OF 3(1-5)] 1 2 show ?case by simp |
820 next |
783 next |
821 case (4 x xs' y ys' p q pn qn) |
784 case (4 x xs' y ys' p q pn qn) |
822 from 4(3-5) 4(7) obtain h1 r1 where |
785 from 4(3-5) 4(7) obtain h1 r1 where |
823 1: "effect (merge p qn) h h1 r1" |
786 1: "effect (merge p qn) h h1 r1" |
824 and 2: "h' = Ref.set q (Node y r1) h1 \<and> r = q" |
787 and 2: "h' = Ref.set q (Node y r1) h1 \<and> r = q" |
825 unfolding merge_simps[of p q] |
788 unfolding merge.simps[of p q] |
826 by (auto elim!: effect_lookupE effect_bindE effect_returnE effect_ifE effect_updateE) |
789 by (auto elim!: effect_lookupE effect_bindE effect_returnE effect_ifE effect_updateE) |
827 from 4(6)[OF 1] assms(7) [OF 4(1-5)] 1 2 show ?case by simp |
790 from 4(6)[OF 1] assms(7) [OF 4(1-5)] 1 2 show ?case by simp |
828 qed |
791 qed |
829 |
792 |
830 |
793 |