src/HOL/Library/Relational.thy
changeset 28145 af3923ed4786
parent 27656 d4f6e64ee7cc
child 28744 9257bb7bcd2d
equal deleted inserted replaced
28144:2c27248bf267 28145:af3923ed4786
    75 next
    75 next
    76   case (Cons x xs)
    76   case (Cons x xs)
    77   from Cons(2) obtain h1 y ys where crel_f: "crel (f x) h h1 y"
    77   from Cons(2) obtain h1 y ys where crel_f: "crel (f x) h h1 y"
    78     and crel_mapM: "crel (mapM f xs) h1 h' ys"
    78     and crel_mapM: "crel (mapM f xs) h1 h' ys"
    79     and r_def: "r = y#ys"
    79     and r_def: "r = y#ys"
    80     unfolding mapM.simps run_drop
    80     unfolding mapM.simps
    81     by (auto elim!: crelE crel_return)
    81     by (auto elim!: crelE crel_return)
    82   from Cons(1)[OF crel_mapM] crel_mapM crel_f assms(3) r_def
    82   from Cons(1)[OF crel_mapM] crel_mapM crel_f assms(3) r_def
    83   show ?case by auto
    83   show ?case by auto
    84 qed
    84 qed
    85 
    85 
   107 
   107 
   108 lemma crel_nth[consumes 1]:
   108 lemma crel_nth[consumes 1]:
   109   assumes "crel (nth a i) h h' r"
   109   assumes "crel (nth a i) h h' r"
   110   obtains "r = (get_array a h) ! i" "h = h'" "i < Heap.length a h"
   110   obtains "r = (get_array a h) ! i" "h = h'" "i < Heap.length a h"
   111   using assms
   111   using assms
   112   unfolding nth_def run_drop
   112   unfolding nth_def
   113   by (auto elim!: crelE crel_if crel_raise crel_length crel_heap)
   113   by (auto elim!: crelE crel_if crel_raise crel_length crel_heap)
   114 
   114 
   115 lemma crel_upd[consumes 1]:
   115 lemma crel_upd[consumes 1]:
   116   assumes "crel (upd i v a) h h' r"
   116   assumes "crel (upd i v a) h h' r"
   117   obtains "r = a" "h' = Heap.upd a i v h"
   117   obtains "r = a" "h' = Heap.upd a i v h"
   118   using assms
   118   using assms
   119   unfolding upd_def run_drop
   119   unfolding upd_def
   120   by (elim crelE crel_if crel_return crel_raise
   120   by (elim crelE crel_if crel_return crel_raise
   121     crel_length crel_heap) auto
   121     crel_length crel_heap) auto
   122 
   122 
   123 (* Strong version of the lemma for this operation is missing *)
   123 (* Strong version of the lemma for this operation is missing *)
   124 lemma crel_of_list_weak:
   124 lemma crel_of_list_weak:
   130 
   130 
   131 lemma crel_map_entry:
   131 lemma crel_map_entry:
   132   assumes "crel (Array.map_entry i f a) h h' r"
   132   assumes "crel (Array.map_entry i f a) h h' r"
   133   obtains "r = a" "h' = Heap.upd a i (f (get_array a h ! i)) h"
   133   obtains "r = a" "h' = Heap.upd a i (f (get_array a h ! i)) h"
   134   using assms
   134   using assms
   135   unfolding Array.map_entry_def run_drop
   135   unfolding Array.map_entry_def
   136   by (elim crelE crel_upd crel_nth) auto
   136   by (elim crelE crel_upd crel_nth) auto
   137 
   137 
   138 lemma crel_swap:
   138 lemma crel_swap:
   139   assumes "crel (Array.swap i x a) h h' r"
   139   assumes "crel (Array.swap i x a) h h' r"
   140   obtains "r = get_array a h ! i" "h' = Heap.upd a i x h"
   140   obtains "r = get_array a h ! i" "h' = Heap.upd a i x h"
   141   using assms
   141   using assms
   142   unfolding Array.swap_def run_drop
   142   unfolding Array.swap_def
   143   by (elim crelE crel_upd crel_nth crel_return) auto
   143   by (elim crelE crel_upd crel_nth crel_return) auto
   144 
   144 
   145 (* Strong version of the lemma for this operation is missing *)
   145 (* Strong version of the lemma for this operation is missing *)
   146 lemma crel_make_weak:
   146 lemma crel_make_weak:
   147   assumes "crel (Array.make n f) h h' r"
   147   assumes "crel (Array.make n f) h h' r"
   173   from Suc(3) have "[Heap.length a h - Suc n..<Heap.length a h] = (Heap.length a h - Suc n)#[Heap.length a h - n..<Heap.length a h]"
   173   from Suc(3) have "[Heap.length a h - Suc n..<Heap.length a h] = (Heap.length a h - Suc n)#[Heap.length a h - n..<Heap.length a h]"
   174     by (simp add: upt_conv_Cons')
   174     by (simp add: upt_conv_Cons')
   175   with Suc(2) obtain r where
   175   with Suc(2) obtain r where
   176     crel_mapM: "crel (mapM (Array.nth a) [Heap.length a h - n..<Heap.length a h]) h h' r"
   176     crel_mapM: "crel (mapM (Array.nth a) [Heap.length a h - n..<Heap.length a h]) h h' r"
   177     and xs_def: "xs = get_array a h ! (Heap.length a h - Suc n) # r"
   177     and xs_def: "xs = get_array a h ! (Heap.length a h - Suc n) # r"
   178     by (auto simp add: run_drop elim!: crelE crel_nth crel_return)
   178     by (auto elim!: crelE crel_nth crel_return)
   179   from Suc(3) have "Heap.length a h - n = Suc (Heap.length a h - Suc n)" 
   179   from Suc(3) have "Heap.length a h - n = Suc (Heap.length a h - Suc n)" 
   180     by arith
   180     by arith
   181   with Suc.hyps[OF crel_mapM] xs_def show ?case
   181   with Suc.hyps[OF crel_mapM] xs_def show ?case
   182     unfolding Heap.length_def
   182     unfolding Heap.length_def
   183     by (auto simp add: nth_drop')
   183     by (auto simp add: nth_drop')
   186 lemma crel_freeze:
   186 lemma crel_freeze:
   187   assumes "crel (Array.freeze a) h h' xs"
   187   assumes "crel (Array.freeze a) h h' xs"
   188   obtains "h = h'" "xs = get_array a h"
   188   obtains "h = h'" "xs = get_array a h"
   189 proof 
   189 proof 
   190   from assms have "crel (mapM (Array.nth a) [0..<Heap.length a h]) h h' xs"
   190   from assms have "crel (mapM (Array.nth a) [0..<Heap.length a h]) h h' xs"
   191     unfolding freeze_def run_drop
   191     unfolding freeze_def
   192     by (auto elim: crelE crel_length)
   192     by (auto elim: crelE crel_length)
   193   hence "crel (mapM (Array.nth a) [(Heap.length a h - Heap.length a h)..<Heap.length a h]) h h' xs"
   193   hence "crel (mapM (Array.nth a) [(Heap.length a h - Heap.length a h)..<Heap.length a h]) h h' xs"
   194     by simp
   194     by simp
   195   from crel_mapM_nth[OF this] show "h = h'" and "xs = get_array a h" by auto
   195   from crel_mapM_nth[OF this] show "h = h'" and "xs = get_array a h" by auto
   196 qed
   196 qed
   209   let ?h1 = "Heap.upd a (Heap.length a h - Suc n) (f (get_array a h ! (Heap.length a h - Suc n))) h"
   209   let ?h1 = "Heap.upd a (Heap.length a h - Suc n) (f (get_array a h ! (Heap.length a h - Suc n))) h"
   210   from Suc(3) have "[Heap.length a h - Suc n..<Heap.length a h] = (Heap.length a h - Suc n)#[Heap.length a h - n..<Heap.length a h]"
   210   from Suc(3) have "[Heap.length a h - Suc n..<Heap.length a h] = (Heap.length a h - Suc n)#[Heap.length a h - n..<Heap.length a h]"
   211     by (simp add: upt_conv_Cons')
   211     by (simp add: upt_conv_Cons')
   212   from Suc(2) this obtain r where
   212   from Suc(2) this obtain r where
   213     crel_mapM: "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a h - n..<Heap.length a h]) ?h1 h' r"
   213     crel_mapM: "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a h - n..<Heap.length a h]) ?h1 h' r"
   214     by (auto simp add: run_drop elim!: crelE crel_map_entry crel_return)
   214     by (auto simp add: elim!: crelE crel_map_entry crel_return)
   215   have length_remains: "Heap.length a ?h1 = Heap.length a h" by simp
   215   have length_remains: "Heap.length a ?h1 = Heap.length a h" by simp
   216   from crel_mapM have crel_mapM': "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a ?h1 - n..<Heap.length a ?h1]) ?h1 h' r"
   216   from crel_mapM have crel_mapM': "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a ?h1 - n..<Heap.length a ?h1]) ?h1 h' r"
   217     by simp
   217     by simp
   218   from Suc(1)[OF this] length_remains Suc(3) show ?case by simp
   218   from Suc(1)[OF this] length_remains Suc(3) show ?case by simp
   219 qed
   219 qed
   234   let ?h1 = "Heap.upd a (Heap.length a h - Suc n) (f (get_array a h ! (Heap.length a h - Suc n))) h"
   234   let ?h1 = "Heap.upd a (Heap.length a h - Suc n) (f (get_array a h ! (Heap.length a h - Suc n))) h"
   235   from Suc(3) have "[Heap.length a h - Suc n..<Heap.length a h] = (Heap.length a h - Suc n)#[Heap.length a h - n..<Heap.length a h]"
   235   from Suc(3) have "[Heap.length a h - Suc n..<Heap.length a h] = (Heap.length a h - Suc n)#[Heap.length a h - n..<Heap.length a h]"
   236     by (simp add: upt_conv_Cons')
   236     by (simp add: upt_conv_Cons')
   237   from Suc(2) this obtain r where
   237   from Suc(2) this obtain r where
   238     crel_mapM: "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a h - n..<Heap.length a h]) ?h1 h' r"
   238     crel_mapM: "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a h - n..<Heap.length a h]) ?h1 h' r"
   239     by (auto simp add: run_drop elim!: crelE crel_map_entry crel_return)
   239     by (auto simp add: elim!: crelE crel_map_entry crel_return)
   240   have length_remains: "Heap.length a ?h1 = Heap.length a h" by simp
   240   have length_remains: "Heap.length a ?h1 = Heap.length a h" by simp
   241   from Suc(3) have less: "Heap.length a h - Suc n < Heap.length a h - n" by arith
   241   from Suc(3) have less: "Heap.length a h - Suc n < Heap.length a h - n" by arith
   242   from Suc(3) have less2: "Heap.length a h - Suc n < Heap.length a h" by arith
   242   from Suc(3) have less2: "Heap.length a h - Suc n < Heap.length a h" by arith
   243   from Suc(4) length_remains have cases: "i = Heap.length a ?h1 - Suc n \<or> i \<ge> Heap.length a ?h1 - n" by arith
   243   from Suc(4) length_remains have cases: "i = Heap.length a ?h1 - Suc n \<or> i \<ge> Heap.length a ?h1 - n" by arith
   244   from crel_mapM have crel_mapM': "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a ?h1 - n..<Heap.length a ?h1]) ?h1 h' r"
   244   from crel_mapM have crel_mapM': "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a ?h1 - n..<Heap.length a ?h1]) ?h1 h' r"
   262   let ?h1 = "Heap.upd a (Heap.length a h - Suc n) (f (get_array a h ! (Heap.length a h - Suc n))) h"
   262   let ?h1 = "Heap.upd a (Heap.length a h - Suc n) (f (get_array a h ! (Heap.length a h - Suc n))) h"
   263   from Suc(3) have "[Heap.length a h - Suc n..<Heap.length a h] = (Heap.length a h - Suc n)#[Heap.length a h - n..<Heap.length a h]"
   263   from Suc(3) have "[Heap.length a h - Suc n..<Heap.length a h] = (Heap.length a h - Suc n)#[Heap.length a h - n..<Heap.length a h]"
   264     by (simp add: upt_conv_Cons')
   264     by (simp add: upt_conv_Cons')
   265   from Suc(2) this obtain r where 
   265   from Suc(2) this obtain r where 
   266     crel_mapM: "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a h - n..<Heap.length a h]) ?h1 h' r"
   266     crel_mapM: "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a h - n..<Heap.length a h]) ?h1 h' r"
   267     by (auto simp add: run_drop elim!: crelE crel_map_entry crel_return)
   267     by (auto elim!: crelE crel_map_entry crel_return)
   268   have length_remains: "Heap.length a ?h1 = Heap.length a h" by simp
   268   have length_remains: "Heap.length a ?h1 = Heap.length a h" by simp
   269   from crel_mapM have crel_mapM': "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a ?h1 - n..<Heap.length a ?h1]) ?h1 h' r"
   269   from crel_mapM have crel_mapM': "crel (mapM (\<lambda>n. map_entry n f a) [Heap.length a ?h1 - n..<Heap.length a ?h1]) ?h1 h' r"
   270     by simp
   270     by simp
   271   from Suc(1)[OF this] length_remains Suc(3) show ?case by simp
   271   from Suc(1)[OF this] length_remains Suc(3) show ?case by simp
   272 qed
   272 qed
   285 lemma crel_map_weak:
   285 lemma crel_map_weak:
   286   assumes crel_map: "crel (Array.map f a) h h' r"
   286   assumes crel_map: "crel (Array.map f a) h h' r"
   287   obtains "r = a" "get_array a h' = List.map f (get_array a h)"
   287   obtains "r = a" "get_array a h' = List.map f (get_array a h)"
   288 proof
   288 proof
   289   from assms crel_mapM_map_entry show  "get_array a h' = List.map f (get_array a h)"
   289   from assms crel_mapM_map_entry show  "get_array a h' = List.map f (get_array a h)"
   290     unfolding Array.map_def run_drop
   290     unfolding Array.map_def
   291     by (fastsimp elim!: crelE crel_length crel_return)
   291     by (fastsimp elim!: crelE crel_length crel_return)
   292   from assms show "r = a"
   292   from assms show "r = a"
   293     unfolding Array.map_def run_drop
   293     unfolding Array.map_def
   294     by (elim crelE crel_return)
   294     by (elim crelE crel_return)
   295 qed
   295 qed
   296 
   296 
   297 subsection {* Elimination rules for reference commands *}
   297 subsection {* Elimination rules for reference commands *}
   298 
   298 
   349 
   349 
   350 lemma crel_change:
   350 lemma crel_change:
   351   assumes "crel (Ref.change f ref) h h' r"
   351   assumes "crel (Ref.change f ref) h h' r"
   352   obtains "h' = set_ref ref (f (get_ref ref h)) h" "r = f (get_ref ref h)"
   352   obtains "h' = set_ref ref (f (get_ref ref h)) h" "r = f (get_ref ref h)"
   353 using assms
   353 using assms
   354 unfolding Ref.change_def run_drop Let_def
   354 unfolding Ref.change_def Let_def
   355 by (auto elim!: crelE crel_lookup crel_update crel_return)
   355 by (auto elim!: crelE crel_lookup crel_update crel_return)
   356 
   356 
   357 subsection {* Elimination rules for the assert command *}
   357 subsection {* Elimination rules for the assert command *}
   358 
   358 
   359 lemma crel_assert[consumes 1]:
   359 lemma crel_assert[consumes 1]:
   444 
   444 
   445 lemma crel_nthI:
   445 lemma crel_nthI:
   446   assumes "i < Heap.length a h"
   446   assumes "i < Heap.length a h"
   447   shows "crel (nth a i) h h ((get_array a h) ! i)"
   447   shows "crel (nth a i) h h ((get_array a h) ! i)"
   448   using assms
   448   using assms
   449   unfolding nth_def run_drop
   449   unfolding nth_def
   450   by (auto intro!: crelI crel_ifI crel_raiseI crel_lengthI crel_heapI')
   450   by (auto intro!: crelI crel_ifI crel_raiseI crel_lengthI crel_heapI')
   451 
   451 
   452 lemma crel_updI:
   452 lemma crel_updI:
   453   assumes "i < Heap.length a h"
   453   assumes "i < Heap.length a h"
   454   shows "crel (upd i v a) h (Heap.upd a i v h) a"
   454   shows "crel (upd i v a) h (Heap.upd a i v h) a"
   455   using assms
   455   using assms
   456   unfolding upd_def run_drop
   456   unfolding upd_def
   457   by (auto intro!: crelI crel_ifI crel_returnI crel_raiseI
   457   by (auto intro!: crelI crel_ifI crel_returnI crel_raiseI
   458     crel_lengthI crel_heapI')
   458     crel_lengthI crel_heapI')
   459 
   459 
   460 (* thm crel_of_listI is missing *)
   460 (* thm crel_of_listI is missing *)
   461 
   461 
   479   shows "crel (ref := v) h (set_ref ref v h) ()"
   479   shows "crel (ref := v) h (set_ref ref v h) ()"
   480   unfolding update_def by (auto intro!: crel_heapI')
   480   unfolding update_def by (auto intro!: crel_heapI')
   481 
   481 
   482 lemma crel_changeI: 
   482 lemma crel_changeI: 
   483   shows "crel (Ref.change f ref) h (set_ref ref (f (get_ref ref h)) h) (f (get_ref ref h))"
   483   shows "crel (Ref.change f ref) h (set_ref ref (f (get_ref ref h)) h) (f (get_ref ref h))"
   484 unfolding change_def Let_def run_drop by (auto intro!: crelI crel_returnI crel_lookupI crel_updateI)
   484 unfolding change_def Let_def by (auto intro!: crelI crel_returnI crel_lookupI crel_updateI)
   485 
   485 
   486 subsection {* Introduction rules for the assert command *}
   486 subsection {* Introduction rules for the assert command *}
   487 
   487 
   488 lemma crel_assertI:
   488 lemma crel_assertI:
   489   assumes "P x"
   489   assumes "P x"
   560   thus ?case
   560   thus ?case
   561     unfolding mapM.simps by (intro noError_return)
   561     unfolding mapM.simps by (intro noError_return)
   562 next
   562 next
   563   case (Cons x xs)
   563   case (Cons x xs)
   564   thus ?case
   564   thus ?case
   565     unfolding mapM.simps run_drop
   565     unfolding mapM.simps
   566     by (auto intro: noErrorI2[of "f x"] noErrorI noError_return)
   566     by (auto intro: noErrorI2[of "f x"] noErrorI noError_return)
   567 qed
   567 qed
   568 
   568 
   569 lemma noError_heap:
   569 lemma noError_heap:
   570   shows "noError (Heap_Monad.heap f) h"
   570   shows "noError (Heap_Monad.heap f) h"
   583 
   583 
   584 lemma noError_upd:
   584 lemma noError_upd:
   585   assumes "i < Heap.length a h"
   585   assumes "i < Heap.length a h"
   586   shows "noError (Array.upd i v a) h"
   586   shows "noError (Array.upd i v a) h"
   587   using assms
   587   using assms
   588   unfolding upd_def run_drop
   588   unfolding upd_def
   589   by (auto intro!: noErrorI noError_if noError_return noError_length noError_heap) (auto elim: crel_length)
   589   by (auto intro!: noErrorI noError_if noError_return noError_length noError_heap) (auto elim: crel_length)
   590 
   590 
   591 lemma noError_nth:
   591 lemma noError_nth:
   592 assumes "i < Heap.length a h"
   592 assumes "i < Heap.length a h"
   593   shows "noError (Array.nth a i) h"
   593   shows "noError (Array.nth a i) h"
   594   using assms
   594   using assms
   595   unfolding nth_def run_drop
   595   unfolding nth_def
   596   by (auto intro!: noErrorI noError_if noError_return noError_length noError_heap) (auto elim: crel_length)
   596   by (auto intro!: noErrorI noError_if noError_return noError_length noError_heap) (auto elim: crel_length)
   597 
   597 
   598 lemma noError_of_list:
   598 lemma noError_of_list:
   599   shows "noError (of_list ls) h"
   599   shows "noError (of_list ls) h"
   600   unfolding of_list_def by (rule noError_heap)
   600   unfolding of_list_def by (rule noError_heap)
   601 
   601 
   602 lemma noError_map_entry:
   602 lemma noError_map_entry:
   603   assumes "i < Heap.length a h"
   603   assumes "i < Heap.length a h"
   604   shows "noError (map_entry i f a) h"
   604   shows "noError (map_entry i f a) h"
   605   using assms
   605   using assms
   606   unfolding map_entry_def run_drop
   606   unfolding map_entry_def
   607   by (auto elim: crel_nth intro!: noErrorI noError_nth noError_upd)
   607   by (auto elim: crel_nth intro!: noErrorI noError_nth noError_upd)
   608 
   608 
   609 lemma noError_swap:
   609 lemma noError_swap:
   610   assumes "i < Heap.length a h"
   610   assumes "i < Heap.length a h"
   611   shows "noError (swap i x a) h"
   611   shows "noError (swap i x a) h"
   612   using assms
   612   using assms
   613   unfolding swap_def run_drop
   613   unfolding swap_def
   614   by (auto elim: crel_nth intro!: noErrorI noError_return noError_nth noError_upd)
   614   by (auto elim: crel_nth intro!: noErrorI noError_return noError_nth noError_upd)
   615 
   615 
   616 lemma noError_make:
   616 lemma noError_make:
   617   shows "noError (make n f) h"
   617   shows "noError (make n f) h"
   618   unfolding make_def
   618   unfolding make_def
   623   "mapM f (xs @ ys) = mapM f xs \<guillemotright>= (\<lambda>xs. mapM f ys \<guillemotright>= (\<lambda>ys. return (xs @ ys)))"
   623   "mapM f (xs @ ys) = mapM f xs \<guillemotright>= (\<lambda>xs. mapM f ys \<guillemotright>= (\<lambda>ys. return (xs @ ys)))"
   624   by (induct xs) (simp_all add: monad_simp)
   624   by (induct xs) (simp_all add: monad_simp)
   625 
   625 
   626 lemma noError_freeze:
   626 lemma noError_freeze:
   627   shows "noError (freeze a) h"
   627   shows "noError (freeze a) h"
   628 unfolding freeze_def run_drop
   628 unfolding freeze_def
   629 by (auto intro!: noErrorI noError_length noError_mapM[of _ _ _ "\<lambda>x. get_array a h ! x"]
   629 by (auto intro!: noErrorI noError_length noError_mapM[of _ _ _ "\<lambda>x. get_array a h ! x"]
   630   noError_nth crel_nthI elim: crel_length)
   630   noError_nth crel_nthI elim: crel_length)
   631 
   631 
   632 lemma noError_mapM_map_entry:
   632 lemma noError_mapM_map_entry:
   633   assumes "n \<le> Heap.length a h"
   633   assumes "n \<le> Heap.length a h"
   639 next
   639 next
   640   case (Suc n)
   640   case (Suc n)
   641   from Suc.prems have "[Heap.length a h - Suc n..<Heap.length a h] = (Heap.length a h - Suc n)#[Heap.length a h - n..<Heap.length a h]"
   641   from Suc.prems have "[Heap.length a h - Suc n..<Heap.length a h] = (Heap.length a h - Suc n)#[Heap.length a h - n..<Heap.length a h]"
   642     by (simp add: upt_conv_Cons')
   642     by (simp add: upt_conv_Cons')
   643   with Suc.hyps[of "(Heap.upd a (Heap.length a h - Suc n) (f (get_array a h ! (Heap.length a h - Suc n))) h)"] Suc.prems show ?case
   643   with Suc.hyps[of "(Heap.upd a (Heap.length a h - Suc n) (f (get_array a h ! (Heap.length a h - Suc n))) h)"] Suc.prems show ?case
   644     by (auto simp add: run_drop intro!: noErrorI noError_return noError_map_entry elim: crel_map_entry)
   644     by (auto simp add: intro!: noErrorI noError_return noError_map_entry elim: crel_map_entry)
   645 qed
   645 qed
   646 
   646 
   647 lemma noError_map:
   647 lemma noError_map:
   648   shows "noError (Array.map f a) h"
   648   shows "noError (Array.map f a) h"
   649 using noError_mapM_map_entry[of "Heap.length a h" a h]
   649 using noError_mapM_map_entry[of "Heap.length a h" a h]
   650 unfolding Array.map_def run_drop
   650 unfolding Array.map_def
   651 by (auto intro: noErrorI noError_length noError_return elim!: crel_length)
   651 by (auto intro: noErrorI noError_length noError_return elim!: crel_length)
   652 
   652 
   653 subsection {* Introduction rules for the reference commands *}
   653 subsection {* Introduction rules for the reference commands *}
   654 
   654 
   655 lemma noError_Ref_new:
   655 lemma noError_Ref_new:
   664   shows "noError (ref := v) h"
   664   shows "noError (ref := v) h"
   665   unfolding update_def by (intro noError_heap)
   665   unfolding update_def by (intro noError_heap)
   666 
   666 
   667 lemma noError_change:
   667 lemma noError_change:
   668   shows "noError (Ref.change f ref) h"
   668   shows "noError (Ref.change f ref) h"
   669   unfolding Ref.change_def run_drop Let_def by (intro noErrorI noError_lookup noError_update noError_return)
   669   unfolding Ref.change_def Let_def by (intro noErrorI noError_lookup noError_update noError_return)
   670 
   670 
   671 subsection {* Introduction rules for the assert command *}
   671 subsection {* Introduction rules for the assert command *}
   672 
   672 
   673 lemma noError_assert:
   673 lemma noError_assert:
   674   assumes "P x"
   674   assumes "P x"