src/HOL/Imperative_HOL/ex/Linked_Lists.thy
changeset 53108 d84c8de81edf
parent 51272 9c8d63b4b6be
child 55414 eab03e9cee8a
equal deleted inserted replaced
53107:57c7294eac0a 53108:d84c8de81edf
   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