7 text {* The crel predicate states that when a computation c runs with the heap h |
7 text {* The crel predicate states that when a computation c runs with the heap h |
8 will result in return value r and a heap h' (if no exception occurs). *} |
8 will result in return value r and a heap h' (if no exception occurs). *} |
9 |
9 |
10 definition crel :: "'a Heap \<Rightarrow> heap \<Rightarrow> heap \<Rightarrow> 'a \<Rightarrow> bool" |
10 definition crel :: "'a Heap \<Rightarrow> heap \<Rightarrow> heap \<Rightarrow> 'a \<Rightarrow> bool" |
11 where |
11 where |
12 crel_def': "crel c h h' r \<longleftrightarrow> Heap_Monad.execute c h = (Inl r, h')" |
12 crel_def': "crel c h h' r \<longleftrightarrow> Heap_Monad.execute c h = Some (r, h')" |
13 |
13 |
14 lemma crel_def: -- FIXME |
14 lemma crel_def: -- FIXME |
15 "crel c h h' r \<longleftrightarrow> (Inl r, h') = Heap_Monad.execute c h" |
15 "crel c h h' r \<longleftrightarrow> Some (r, h') = Heap_Monad.execute c h" |
16 unfolding crel_def' by auto |
16 unfolding crel_def' by auto |
17 |
17 |
18 lemma crel_deterministic: "\<lbrakk> crel f h h' a; crel f h h'' b \<rbrakk> \<Longrightarrow> (a = b) \<and> (h' = h'')" |
18 lemma crel_deterministic: "\<lbrakk> crel f h h' a; crel f h h'' b \<rbrakk> \<Longrightarrow> (a = b) \<and> (h' = h'')" |
19 unfolding crel_def' by auto |
19 unfolding crel_def' by auto |
20 |
20 |
26 subsection {* Elimination rules for basic monadic commands *} |
26 subsection {* Elimination rules for basic monadic commands *} |
27 |
27 |
28 lemma crelE[consumes 1]: |
28 lemma crelE[consumes 1]: |
29 assumes "crel (f >>= g) h h'' r'" |
29 assumes "crel (f >>= g) h h'' r'" |
30 obtains h' r where "crel f h h' r" "crel (g r) h' h'' r'" |
30 obtains h' r where "crel f h h' r" "crel (g r) h' h'' r'" |
31 using assms |
31 using assms by (auto simp add: crel_def bindM_def split: option.split_asm) |
32 by (auto simp add: crel_def bindM_def Let_def prod_case_beta split_def Pair_fst_snd_eq split add: sum.split_asm) |
|
33 |
32 |
34 lemma crelE'[consumes 1]: |
33 lemma crelE'[consumes 1]: |
35 assumes "crel (f >> g) h h'' r'" |
34 assumes "crel (f >> g) h h'' r'" |
36 obtains h' r where "crel f h h' r" "crel g h' h'' r'" |
35 obtains h' r where "crel f h h' r" "crel g h' h'' r'" |
37 using assms |
36 using assms |
84 qed |
83 qed |
85 |
84 |
86 lemma crel_heap: |
85 lemma crel_heap: |
87 assumes "crel (Heap_Monad.heap f) h h' r" |
86 assumes "crel (Heap_Monad.heap f) h h' r" |
88 obtains "h' = snd (f h)" "r = fst (f h)" |
87 obtains "h' = snd (f h)" "r = fst (f h)" |
89 using assms |
88 using assms by (cases "f h") (simp add: crel_def) |
90 unfolding heap_def crel_def apfst_def split_def prod_fun_def by simp_all |
89 |
91 |
90 |
92 subsection {* Elimination rules for array commands *} |
91 subsection {* Elimination rules for array commands *} |
93 |
92 |
94 lemma crel_length: |
93 lemma crel_length: |
95 assumes "crel (length a) h h' r" |
94 assumes "crel (length a) h h' r" |
367 unfolding crel_def bindM_def Let_def assert_def |
366 unfolding crel_def bindM_def Let_def assert_def |
368 raise_def return_def prod_case_beta |
367 raise_def return_def prod_case_beta |
369 apply (cases f) |
368 apply (cases f) |
370 apply simp |
369 apply simp |
371 apply (simp add: expand_fun_eq split_def) |
370 apply (simp add: expand_fun_eq split_def) |
|
371 apply (auto split: option.split) |
|
372 apply (erule_tac x="x" in meta_allE) |
372 apply auto |
373 apply auto |
373 apply (case_tac "fst (fun x)") |
|
374 apply (simp_all add: Pair_fst_snd_eq) |
|
375 apply (erule_tac x="x" in meta_allE) |
|
376 apply fastsimp |
|
377 done |
374 done |
378 |
375 |
379 section {* Introduction rules *} |
376 section {* Introduction rules *} |
380 |
377 |
381 subsection {* Introduction rules for basic monadic commands *} |
378 subsection {* Introduction rules for basic monadic commands *} |
500 assumes "\<And> x h h1 h2 h' s z r. crel (f x) h h1 (Inr s) \<Longrightarrow> crel (MREC f g s) h1 h2 z \<Longrightarrow> P s h1 h2 z |
497 assumes "\<And> x h h1 h2 h' s z r. crel (f x) h h1 (Inr s) \<Longrightarrow> crel (MREC f g s) h1 h2 z \<Longrightarrow> P s h1 h2 z |
501 \<Longrightarrow> crel (g x s z) h2 h' r \<Longrightarrow> P x h h' r" |
498 \<Longrightarrow> crel (g x s z) h2 h' r \<Longrightarrow> P x h h' r" |
502 shows "P x h h' r" |
499 shows "P x h h' r" |
503 proof (rule MREC_pinduct[OF assms(1)[unfolded crel_def, symmetric]]) |
500 proof (rule MREC_pinduct[OF assms(1)[unfolded crel_def, symmetric]]) |
504 fix x h h1 h2 h' s z r |
501 fix x h h1 h2 h' s z r |
505 assume "Heap_Monad.execute (f x) h = (Inl (Inr s), h1)" |
502 assume "Heap_Monad.execute (f x) h = Some (Inr s, h1)" |
506 "Heap_Monad.execute (MREC f g s) h1 = (Inl z, h2)" |
503 "Heap_Monad.execute (MREC f g s) h1 = Some (z, h2)" |
507 "P s h1 h2 z" |
504 "P s h1 h2 z" |
508 "Heap_Monad.execute (g x s z) h2 = (Inl r, h')" |
505 "Heap_Monad.execute (g x s z) h2 = Some (r, h')" |
509 from assms(3)[unfolded crel_def, OF this(1)[symmetric] this(2)[symmetric] this(3) this(4)[symmetric]] |
506 from assms(3)[unfolded crel_def, OF this(1)[symmetric] this(2)[symmetric] this(3) this(4)[symmetric]] |
510 show "P x h h' r" . |
507 show "P x h h' r" . |
511 next |
508 next |
512 qed (auto simp add: assms(2)[unfolded crel_def]) |
509 qed (auto simp add: assms(2)[unfolded crel_def]) |
513 |
510 |
517 where we only would like to show that the computation does not result in a exception for heap h, |
514 where we only would like to show that the computation does not result in a exception for heap h, |
518 but we do not care about statements about the resulting heap and return value.*} |
515 but we do not care about statements about the resulting heap and return value.*} |
519 |
516 |
520 definition noError :: "'a Heap \<Rightarrow> heap \<Rightarrow> bool" |
517 definition noError :: "'a Heap \<Rightarrow> heap \<Rightarrow> bool" |
521 where |
518 where |
522 "noError c h \<longleftrightarrow> (\<exists>r h'. (Inl r, h') = Heap_Monad.execute c h)" |
519 "noError c h \<longleftrightarrow> (\<exists>r h'. Some (r, h') = Heap_Monad.execute c h)" |
523 |
520 |
524 lemma noError_def': -- FIXME |
521 lemma noError_def': -- FIXME |
525 "noError c h \<longleftrightarrow> (\<exists>r h'. Heap_Monad.execute c h = (Inl r, h'))" |
522 "noError c h \<longleftrightarrow> (\<exists>r h'. Heap_Monad.execute c h = Some (r, h'))" |
526 unfolding noError_def apply auto proof - |
523 unfolding noError_def apply auto proof - |
527 fix r h' |
524 fix r h' |
528 assume "(Inl r, h') = Heap_Monad.execute c h" |
525 assume "Some (r, h') = Heap_Monad.execute c h" |
529 then have "Heap_Monad.execute c h = (Inl r, h')" .. |
526 then have "Heap_Monad.execute c h = Some (r, h')" .. |
530 then show "\<exists>r h'. Heap_Monad.execute c h = (Inl r, h')" by blast |
527 then show "\<exists>r h'. Heap_Monad.execute c h = Some (r, h')" by blast |
531 qed |
528 qed |
532 |
529 |
533 subsection {* Introduction rules for basic monadic commands *} |
530 subsection {* Introduction rules for basic monadic commands *} |
534 |
531 |
535 lemma noErrorI: |
532 lemma noErrorI: |
638 by (auto intro: noError_of_list) |
635 by (auto intro: noError_of_list) |
639 |
636 |
640 (*TODO: move to HeapMonad *) |
637 (*TODO: move to HeapMonad *) |
641 lemma mapM_append: |
638 lemma mapM_append: |
642 "mapM f (xs @ ys) = mapM f xs \<guillemotright>= (\<lambda>xs. mapM f ys \<guillemotright>= (\<lambda>ys. return (xs @ ys)))" |
639 "mapM f (xs @ ys) = mapM f xs \<guillemotright>= (\<lambda>xs. mapM f ys \<guillemotright>= (\<lambda>ys. return (xs @ ys)))" |
643 by (induct xs) (simp_all add: monad_simp) |
640 by (induct xs) simp_all |
644 |
641 |
645 lemma noError_freeze: |
642 lemma noError_freeze: |
646 shows "noError (freeze a) h" |
643 shows "noError (freeze a) h" |
647 unfolding freeze_def |
644 unfolding freeze_def |
648 by (auto intro!: noErrorI noError_length noError_mapM[of _ _ _ "\<lambda>x. get_array a h ! x"] |
645 by (auto intro!: noErrorI noError_length noError_mapM[of _ _ _ "\<lambda>x. get_array a h ! x"] |