12 |
12 |
13 subsection {* Maybe monad type *} |
13 subsection {* Maybe monad type *} |
14 |
14 |
15 defaultsort cpo |
15 defaultsort cpo |
16 |
16 |
17 types 'a maybe = "one ++ 'a u" |
17 pcpodef (open) 'a maybe = "UNIV::(one ++ 'a u) set" |
|
18 by simp |
18 |
19 |
19 constdefs |
20 constdefs |
20 fail :: "'a maybe" |
21 fail :: "'a maybe" |
21 "fail \<equiv> sinl\<cdot>ONE" |
22 "fail \<equiv> Abs_maybe (sinl\<cdot>ONE)" |
22 |
23 |
23 return :: "'a \<rightarrow> 'a maybe" |
24 return :: "'a \<rightarrow> 'a maybe" |
24 "return \<equiv> sinr oo up" |
25 "return \<equiv> \<Lambda> x. Abs_maybe (sinr\<cdot>(up\<cdot>x))" |
|
26 |
|
27 maybe_when :: "'b \<rightarrow> ('a \<rightarrow> 'b) \<rightarrow> 'a maybe \<rightarrow> 'b::pcpo" |
|
28 "maybe_when \<equiv> \<Lambda> f r m. sscase\<cdot>(\<Lambda> x. f)\<cdot>(fup\<cdot>r)\<cdot>(Rep_maybe m)" |
25 |
29 |
26 lemma maybeE: |
30 lemma maybeE: |
27 "\<lbrakk>p = \<bottom> \<Longrightarrow> Q; p = fail \<Longrightarrow> Q; \<And>x. p = return\<cdot>x \<Longrightarrow> Q\<rbrakk> \<Longrightarrow> Q" |
31 "\<lbrakk>p = \<bottom> \<Longrightarrow> Q; p = fail \<Longrightarrow> Q; \<And>x. p = return\<cdot>x \<Longrightarrow> Q\<rbrakk> \<Longrightarrow> Q" |
28 apply (unfold fail_def return_def) |
32 apply (unfold fail_def return_def) |
29 apply (rule_tac p=p in ssumE, simp) |
33 apply (cases p, rename_tac r) |
|
34 apply (rule_tac p=r in ssumE, simp add: Abs_maybe_strict) |
30 apply (rule_tac p=x in oneE, simp, simp) |
35 apply (rule_tac p=x in oneE, simp, simp) |
31 apply (rule_tac p=y in upE, simp, simp) |
36 apply (rule_tac p=y in upE, simp, simp add: cont_Abs_maybe) |
32 done |
37 done |
33 |
38 |
34 lemma return_defined [simp]: "return\<cdot>x \<noteq> \<bottom>" |
39 lemma return_defined [simp]: "return\<cdot>x \<noteq> \<bottom>" |
35 by (simp add: return_def) |
40 by (simp add: return_def cont_Abs_maybe Abs_maybe_defined) |
36 |
41 |
37 lemma fail_defined [simp]: "fail \<noteq> \<bottom>" |
42 lemma fail_defined [simp]: "fail \<noteq> \<bottom>" |
38 by (simp add: fail_def) |
43 by (simp add: fail_def Abs_maybe_defined) |
39 |
44 |
40 lemma return_eq [simp]: "(return\<cdot>x = return\<cdot>y) = (x = y)" |
45 lemma return_eq [simp]: "(return\<cdot>x = return\<cdot>y) = (x = y)" |
41 by (simp add: return_def) |
46 by (simp add: return_def cont_Abs_maybe Abs_maybe_inject) |
42 |
47 |
43 lemma return_neq_fail [simp]: |
48 lemma return_neq_fail [simp]: |
44 "return\<cdot>x \<noteq> fail" "fail \<noteq> return\<cdot>x" |
49 "return\<cdot>x \<noteq> fail" "fail \<noteq> return\<cdot>x" |
45 by (simp_all add: return_def fail_def) |
50 by (simp_all add: return_def fail_def cont_Abs_maybe Abs_maybe_inject) |
|
51 |
|
52 lemma maybe_when_rews [simp]: |
|
53 "maybe_when\<cdot>f\<cdot>r\<cdot>\<bottom> = \<bottom>" |
|
54 "maybe_when\<cdot>f\<cdot>r\<cdot>fail = f" |
|
55 "maybe_when\<cdot>f\<cdot>r\<cdot>(return\<cdot>x) = r\<cdot>x" |
|
56 by (simp_all add: return_def fail_def maybe_when_def cont_Rep_maybe |
|
57 cont_Abs_maybe Abs_maybe_inverse Rep_maybe_strict) |
|
58 |
|
59 translations |
|
60 "case m of fail \<Rightarrow> t1 | return\<cdot>x \<Rightarrow> t2" == "maybe_when\<cdot>t1\<cdot>(\<Lambda> x. t2)\<cdot>m" |
46 |
61 |
47 |
62 |
48 subsubsection {* Monadic bind operator *} |
63 subsubsection {* Monadic bind operator *} |
49 |
64 |
50 constdefs |
65 constdefs |
51 bind :: "'a maybe \<rightarrow> ('a \<rightarrow> 'b maybe) \<rightarrow> 'b maybe" |
66 bind :: "'a maybe \<rightarrow> ('a \<rightarrow> 'b maybe) \<rightarrow> 'b maybe" |
52 "bind \<equiv> \<Lambda> m f. sscase\<cdot>sinl\<cdot>(fup\<cdot>f)\<cdot>m" |
67 "bind \<equiv> \<Lambda> m f. case m of fail \<Rightarrow> fail | return\<cdot>x \<Rightarrow> f\<cdot>x" |
53 |
|
54 syntax ">>=" :: "['a maybe, 'a \<rightarrow> 'b maybe] \<Rightarrow> 'b maybe" (infixl ">>=" 50) |
|
55 translations "m >>= f" == "bind\<cdot>m\<cdot>f" |
|
56 |
|
57 nonterminals |
|
58 maybebind maybebinds |
|
59 |
|
60 syntax |
|
61 "_MBIND" :: "pttrn \<Rightarrow> 'a maybe \<Rightarrow> maybebind" ("(2_ <-/ _)" 10) |
|
62 "" :: "maybebind \<Rightarrow> maybebinds" ("_") |
|
63 |
|
64 "_MBINDS" :: "[maybebind, maybebinds] \<Rightarrow> maybebinds" ("_;/ _") |
|
65 "_MDO" :: "[maybebinds, 'a maybe] \<Rightarrow> 'a maybe" ("(do _;/ (_))" 10) |
|
66 |
|
67 translations |
|
68 "_MDO (_MBINDS b bs) e" == "_MDO b (_MDO bs e)" |
|
69 "do (x,y) <- m; e" == "m >>= (LAM <x,y>. e)" |
|
70 "do x <- m; e" == "m >>= (LAM x. e)" |
|
71 |
68 |
72 text {* monad laws *} |
69 text {* monad laws *} |
73 |
70 |
74 lemma bind_strict [simp]: "UU >>= f = UU" |
71 lemma bind_strict [simp]: "bind\<cdot>\<bottom>\<cdot>f = \<bottom>" |
75 by (simp add: bind_def) |
72 by (simp add: bind_def) |
76 |
73 |
77 lemma bind_fail [simp]: "fail >>= f = fail" |
74 lemma bind_fail [simp]: "bind\<cdot>fail\<cdot>f = fail" |
78 by (simp add: bind_def fail_def) |
75 by (simp add: bind_def) |
79 |
76 |
80 lemma left_unit [simp]: "(return\<cdot>a) >>= k = k\<cdot>a" |
77 lemma left_unit [simp]: "bind\<cdot>(return\<cdot>a)\<cdot>k = k\<cdot>a" |
81 by (simp add: bind_def return_def) |
78 by (simp add: bind_def) |
82 |
79 |
83 lemma right_unit [simp]: "m >>= return = m" |
80 lemma right_unit [simp]: "bind\<cdot>m\<cdot>return = m" |
84 by (rule_tac p=m in maybeE, simp_all) |
81 by (rule_tac p=m in maybeE, simp_all) |
85 |
82 |
86 lemma bind_assoc [simp]: |
83 lemma bind_assoc: |
87 "(do b <- (do a <- m; k\<cdot>a); h\<cdot>b) = (do a <- m; b <- k\<cdot>a; h\<cdot>b)" |
84 "bind\<cdot>(bind\<cdot>m\<cdot>k)\<cdot>h = bind\<cdot>m\<cdot>(\<Lambda> a. bind\<cdot>(k\<cdot>a)\<cdot>h)" |
88 by (rule_tac p=m in maybeE, simp_all) |
85 by (rule_tac p=m in maybeE, simp_all) |
89 |
86 |
90 subsubsection {* Run operator *} |
87 subsubsection {* Run operator *} |
91 |
88 |
92 constdefs |
89 constdefs |
93 run:: "'a::pcpo maybe \<rightarrow> 'a" |
90 run:: "'a maybe \<rightarrow> 'a::pcpo" |
94 "run \<equiv> sscase\<cdot>\<bottom>\<cdot>(fup\<cdot>ID)" |
91 "run \<equiv> maybe_when\<cdot>\<bottom>\<cdot>ID" |
95 |
92 |
96 text {* rewrite rules for run *} |
93 text {* rewrite rules for run *} |
97 |
94 |
98 lemma run_strict [simp]: "run\<cdot>\<bottom> = \<bottom>" |
95 lemma run_strict [simp]: "run\<cdot>\<bottom> = \<bottom>" |
99 by (simp add: run_def) |
96 by (simp add: run_def) |
100 |
97 |
101 lemma run_fail [simp]: "run\<cdot>fail = \<bottom>" |
98 lemma run_fail [simp]: "run\<cdot>fail = \<bottom>" |
102 by (simp add: run_def fail_def) |
99 by (simp add: run_def) |
103 |
100 |
104 lemma run_return [simp]: "run\<cdot>(return\<cdot>x) = x" |
101 lemma run_return [simp]: "run\<cdot>(return\<cdot>x) = x" |
105 by (simp add: run_def return_def) |
102 by (simp add: run_def) |
106 |
103 |
107 subsubsection {* Monad plus operator *} |
104 subsubsection {* Monad plus operator *} |
108 |
105 |
109 constdefs |
106 constdefs |
110 mplus :: "'a maybe \<rightarrow> 'a maybe \<rightarrow> 'a maybe" |
107 mplus :: "'a maybe \<rightarrow> 'a maybe \<rightarrow> 'a maybe" |
111 "mplus \<equiv> \<Lambda> m1 m2. sscase\<cdot>(\<Lambda> x. m2)\<cdot>(fup\<cdot>return)\<cdot>m1" |
108 "mplus \<equiv> \<Lambda> m1 m2. case m1 of fail \<Rightarrow> m2 | return\<cdot>x \<Rightarrow> m1" |
112 |
109 |
113 syntax "+++" :: "['a maybe, 'a maybe] \<Rightarrow> 'a maybe" (infixr "+++" 65) |
110 syntax "+++" :: "['a maybe, 'a maybe] \<Rightarrow> 'a maybe" (infixr "+++" 65) |
114 translations "m1 +++ m2" == "mplus\<cdot>m1\<cdot>m2" |
111 translations "m1 +++ m2" == "mplus\<cdot>m1\<cdot>m2" |
115 |
112 |
116 text {* rewrite rules for mplus *} |
113 text {* rewrite rules for mplus *} |
117 |
114 |
118 lemma mplus_strict [simp]: "\<bottom> +++ m = \<bottom>" |
115 lemma mplus_strict [simp]: "\<bottom> +++ m = \<bottom>" |
119 by (simp add: mplus_def) |
116 by (simp add: mplus_def) |
120 |
117 |
121 lemma mplus_fail [simp]: "fail +++ m = m" |
118 lemma mplus_fail [simp]: "fail +++ m = m" |
122 by (simp add: mplus_def fail_def) |
119 by (simp add: mplus_def) |
123 |
120 |
124 lemma mplus_return [simp]: "return\<cdot>x +++ m = return\<cdot>x" |
121 lemma mplus_return [simp]: "return\<cdot>x +++ m = return\<cdot>x" |
125 by (simp add: mplus_def return_def) |
122 by (simp add: mplus_def) |
126 |
123 |
127 lemma mplus_fail2 [simp]: "m +++ fail = m" |
124 lemma mplus_fail2 [simp]: "m +++ fail = m" |
128 by (rule_tac p=m in maybeE, simp_all) |
125 by (rule_tac p=m in maybeE, simp_all) |
129 |
126 |
130 lemma mplus_assoc: "(x +++ y) +++ z = x +++ (y +++ z)" |
127 lemma mplus_assoc: "(x +++ y) +++ z = x +++ (y +++ z)" |