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" |
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" |