source: Deliverables/D3.1/C-semantics/IOMonad.ma @ 411

Last change on this file since 411 was 411, checked in by campbell, 9 years ago

Note associativity of IOMonad, subject to extensionality.

File size: 8.5 KB
Line 
1include "Plogic/russell_support.ma".
2include "extralib.ma".
3include "Errors.ma".
4
5(* IO monad *)
6
7ninductive IO (output:Type) (input:output → Type) (T:Type) : Type ≝
8| Interact : ∀o:output. (input o → IO output input T) → IO output input T
9| Value : T → IO output input T
10| Wrong : IO output input T.
11
12nlet rec bindIO (O:Type) (I:O → Type) (T,T':Type) (v:IO O I T) (f:T → IO O I T') on v : IO O I T' ≝
13match v with
14[ Interact out k ⇒ (Interact ??? out (λres. bindIO O I T T' (k res) f))
15| Value v' ⇒ (f v')
16| Wrong ⇒ Wrong O I T'
17].
18
19nlet rec bindIO2 (O:Type) (I:O → Type) (T1,T2,T':Type) (v:IO O I (T1×T2)) (f:T1 → T2 → IO O I T') on v : IO O I T' ≝
20match v with
21[ Interact out k ⇒ (Interact ??? out (λres. bindIO2 ?? T1 T2 T' (k res) f))
22| Value v' ⇒ match v' with [ mk_pair v1 v2 ⇒ f v1 v2 ]
23| Wrong ⇒ Wrong ?? T'
24].
25
26ndefinition err_to_io : ∀O,I,T. res T → IO O I T ≝
27λO,I,T,v. match v with [ OK v' ⇒ Value O I T v' | Error ⇒ Wrong O I T ].
28ncoercion err_to_io : ∀O,I,A.∀c:res A.IO O I A ≝ err_to_io on _c:res ? to IO ???.
29ndefinition err_to_io_sig : ∀O,I,T.∀P:T → Prop. res (sigma T P) → IO O I (sigma T P) ≝
30λO,I,T,P,v. match v with [ OK v' ⇒ Value O I (sigma T P) v' | Error ⇒ Wrong O I (sigma T P) ].
31(*ncoercion err_to_io_sig : ∀O,I,A.∀P:A → Prop.∀c:res (sigma A P).IO O I (sigma A P) ≝ err_to_io_sig on _c:res (sigma ??) to IO ?? (sigma ??).*)
32
33
34(* If the original definitions are vague enough, do I need to do this? *)
35notation > "! ident v ← e; e'" with precedence 40 for @{'bindIO ${e} (λ${ident v}.${e'})}.
36notation > "! ident v : ty ← e; e'" with precedence 40 for @{'bindIO ${e} (λ${ident v} : ${ty}.${e'})}.
37notation < "vbox(! \nbsp ident v ← e; break e')" with precedence 40 for @{'bindIO ${e} (λ${ident v}.${e'})}.
38notation < "vbox(! \nbsp ident v : ty ← e; break e')" with precedence 40 for @{'bindIO ${e} (λ${ident v} : ${ty}.${e'})}.
39notation > "! 〈ident v1, ident v2〉 ← e; e'" with precedence 40 for @{'bindIO2 ${e} (λ${ident v1}.λ${ident v2}.${e'})}.
40notation > "! 〈ident v1 : ty1, ident v2 : ty2〉 ← e; e'" with precedence 40 for @{'bindIO2 ${e} (λ${ident v1} : ${ty1}.λ${ident v2} : ${ty2}.${e'})}.
41notation < "vbox(! \nbsp 〈ident v1, ident v2〉 ← e; break e')" with precedence 40 for @{'bindIO2 ${e} (λ${ident v1}.λ${ident v2}.${e'})}.
42notation < "vbox(! \nbsp 〈ident v1 : ty1, ident v2 : ty2〉 ← e; break e')" with precedence 40 for @{'bindIO2 ${e} (λ${ident v1} : ${ty1}.λ${ident v2} : ${ty2}.${e'})}.
43interpretation "IO monad bind" 'bindIO e f = (bindIO ???? e f).
44interpretation "IO monad pair bind" 'bindIO2 e f = (bindIO2 ????? e f).
45(**)
46nlet rec P_io O I (A:Type) (P:A → Prop) (v:IO O I A) on v : Prop ≝
47match v return λ_.Prop with
48[ Wrong ⇒ True
49| Value z ⇒ P z
50| Interact out k ⇒ ∀v'.P_io O I A P (k v')
51].
52
53nlet rec P_io' O I (A:Type) (P:A → Prop) (v:IO O I A) on v : Prop ≝
54match v return λ_.Prop with
55[ Wrong ⇒ False
56| Value z ⇒ P z
57| Interact out k ⇒ ∀v'.P_io' O I A P (k v')
58].
59
60ndefinition P_to_P_option_io : ∀O,I,A.∀P:A → Prop.option (IO O I A) → Prop ≝
61  λO,I,A,P,a.match a with
62   [ None ⇒ False
63   | Some y ⇒ P_io O I A P y
64   ].
65
66nlet rec io_inject_0 O I (A:Type) (P:A → Prop) (a:IO O I A) (p:P_io O I A P a) on a : IO O I (sigma A P) ≝
67(match a return λa'.P_io O I A P a' → ? with
68 [ Wrong ⇒ λ_. Wrong O I ?
69 | Value c ⇒ λp'. Value ??? (sig_intro A P c p')
70 | Interact out k ⇒ λp'. Interact ??? out (λv. io_inject_0 O I A P (k v) (p' v))
71 ]) p.
72
73ndefinition io_inject : ∀O,I,A.∀P:A → Prop.∀a:option (IO O I A).∀p:P_to_P_option_io O I A P a.IO O I (sigma A P) ≝
74  λO,I,A.λP:A → Prop.λa:option (IO O I A).λp:P_to_P_option_io O I A P a.
75  (match a return λa'.P_to_P_option_io O I A P a' → IO O I (sigma A P) with
76   [ None ⇒ λp'.?
77   | Some b ⇒ λp'. io_inject_0 O I A P b p'
78   ]) p.
79nelim p'; nqed.
80
81nlet rec io_eject O I (A:Type) (P: A → Prop) (a:IO O I (sigma A P)) on a : IO O I A ≝
82match a with
83[ Wrong ⇒ Wrong ???
84| Value b ⇒ match b with [ sig_intro w p ⇒ Value ??? w]
85| Interact out k ⇒ Interact ??? out (λv. io_eject ?? A P (k v))
86].
87
88ncoercion io_inject :
89  ∀O,I,A.∀P:A → Prop.∀a.∀p:P_to_P_option_io O I ? P a.IO O I (sigma A P) ≝ io_inject
90  on a:option (IO ???) to IO ?? (sigma ? ?).
91ncoercion io_eject : ∀O,I,A.∀P:A → Prop.∀c:IO O I (sigma A P).IO O I A ≝ io_eject
92  on _c:IO ?? (sigma ? ?) to IO ???.
93
94ndefinition opt_to_io : ∀O,I,T.option T → IO O I T ≝
95λO,I,T,v. match v with [ None ⇒ Wrong ?? T | Some v' ⇒ Value ??? v' ].
96ncoercion opt_to_io : ∀O,I,T.∀v:option T. IO O I T ≝ opt_to_io on _v:option ? to IO ???.
97
98nlemma sig_bindIO_OK: ∀O,I,A,B. ∀P:A → Prop. ∀P':B → Prop. ∀e:IO O I (sigma A P). ∀f:sigma A P → IO O I B.
99  (∀v:A. ∀p:P v. P_io O I ? P' (f (sig_intro A P v p))) →
100  P_io O I ? P' (bindIO O I (sigma A P) B e f).
101#O I A B P P' e f; nelim e;
102##[ #out k IH; #IH'; nwhd; #res; napply IH; //;
103##| #v0; nelim v0; #v Hv IH; nwhd; napply IH;
104##| //;
105##] nqed.
106
107nlemma sig_bindIO2_OK: ∀O,I,A,B,C. ∀P:(A×B) → Prop. ∀P':C → Prop. ∀e:IO O I (sigma (A×B) P). ∀f: A → B → IO O I C.
108  (∀vA:A.∀vB:B. ∀p:P 〈vA,vB〉. P_io O I ? P' (f vA vB)) →
109  P_io O I ? P' (bindIO2 O I A B C e f).
110#I O A B C P P' e f; nelim e;
111##[ #out k IH; #IH'; nwhd; #res; napply IH; napply IH';
112##| #v0; nelim v0; #v; nelim v; #vA vB Hv IH; napply IH; //;
113##| //;
114##] nqed.
115
116nlemma opt_bindIO_OK: ∀O,I,A,B. ∀P:B → Prop. ∀e:option A. ∀f: A → IO O I B.
117  (∀v:A. e = Some A v → P_io O I ? P (f v)) →
118  P_io O I ? P (bindIO O I A B e f).
119#I O A B P e; nelim e; //; #v f H; napply H; //;
120nqed.
121
122nlemma opt_bindIO2_OK: ∀O,I,A,B,C. ∀P:C → Prop. ∀e:option (A×B). ∀f: A → B → IO O I C.
123  (∀vA:A.∀vB:B. e = Some (A×B) 〈vA,vB〉 → P_io O I ? P (f vA vB)) →
124  P_io O I ? P (bindIO2 O I A B C e f).
125#I O A B C P e; nelim e; //; #v; ncases v; #vA vB f H; napply H; //;
126nqed.
127
128nlemma res_bindIO_OK: ∀O,I,A,B. ∀P:B → Prop. ∀e:res A. ∀f: A → IO O I B.
129  (∀v:A. e = OK A v → P_io O I ? P (f v)) →
130  P_io O I ? P (bindIO O I A B e f).
131#I O A B P e; nelim e; //; #v f H; napply H; //;
132nqed.
133
134nlemma res_bindIO2_OK: ∀O,I,A,B,C. ∀P:C → Prop. ∀e:res (A×B). ∀f: A → B → IO O I C.
135  (∀vA:A.∀vB:B. e = OK (A×B) 〈vA,vB〉 → P_io O I ? P (f vA vB)) →
136  P_io O I ? P (bindIO2 O I A B C e f).
137#I O A B C P e; nelim e; //; #v; ncases v; #vA vB f H; napply H; //;
138nqed.
139
140nlemma bindIO_OK: ∀O,I,A,B. ∀P:B → Prop. ∀e:IO O I A. ∀f: A → IO O I B.
141  (∀v:A. P_io O I ? P (f v)) →
142  P_io O I ? P (bindIO O I A B e f).
143#I O A B P e; nelim e;
144##[ #out k IH; #f H; nwhd; #res; napply IH; //;
145##| #v f H; napply H;
146##| //;
147##] nqed.
148
149nlemma bindIO2_OK: ∀O,I,A,B,C. ∀P:C → Prop. ∀e:IO O I (A×B). ∀f: A → B → IO O I C.
150  (∀v1:A.∀v2:B. P_io O I ? P (f v1 v2)) →
151  P_io O I ? P (bindIO2 O I A B C e f).
152#I O A B C P e; nelim e;
153##[ #out k IH; #f H; nwhd; #res; napply IH; //;
154##| #v; ncases v; #v1 v2 f H; napply H;
155##| //;
156##] nqed.
157
158nlemma P_bindIO_OK: ∀O,I,A,B. ∀P':A → Prop. ∀P:B → Prop. ∀e:IO O I A. ∀f: A → IO O I B.
159  P_io … P' e →
160  (∀v:A. P' v → P_io O I ? P (f v)) →
161  P_io O I ? P (bindIO O I A B e f).
162#I O A B P' P e; nelim e;
163##[ #out k IH f He H; nwhd in He ⊢ %; #res; napply IH; /2/;
164##| #v f He H; napply H; napply He;
165##| //;
166##] nqed.
167
168nlemma P_bindIO2_OK: ∀O,I,A,B,C. ∀P':A×B → Prop. ∀P:C → Prop. ∀e:IO O I (A×B). ∀f: A → B → IO O I C.
169  P_io … P' e →
170  (∀v1:A.∀v2:B. P' 〈v1,v2〉 → P_io O I ? P (f v1 v2)) →
171  P_io O I ? P (bindIO2 O I A B C e f).
172#I O A B C P' P e; nelim e;
173##[ #out k IH f He H; nwhd in He ⊢ %; #res; napply IH; /2/;
174##| #v; ncases v; #v1 v2 f He H; napply H; napply He;
175##| //;
176##] nqed.
177
178
179(* Is there a way to prove this without extensionality? *)
180
181nlemma bind_assoc_r: ∀O,I,A,B,C,e,f,g.
182  ∀ext:(∀T1,T2:Type.∀f,f':T1 → T2.(∀x.f x = f' x) → f = f').
183  bindIO O I B C (bindIO O I A B e f) g = bindIO O I A C e (λx.bindIO O I B C (f x) g).
184#O I A B C e f g ext; nelim e;
185##[ #o k IH; nwhd in ⊢ (??%%); napply eq_f;
186    napply ext; napply IH;
187##| #v; napply refl;
188##| napply refl;
189##] nqed.
190
191
192nlemma extract_subset_pair_io: ∀O,I,A,B,C,P. ∀e:{e:A×B | P e}. ∀Q:A→B→IO O I C. ∀R:C→Prop.
193  (∀a,b. eject ?? e = 〈a,b〉 → P 〈a,b〉 → P_io O I ? R (Q a b)) →
194  P_io O I ? R (match eject ?? e with [ mk_pair a b ⇒ Q a b ]).
195#I O A B C P e Q R; ncases e; #e'; ncases e'; nnormalize;
196##[ *;
197##| #e''; ncases e''; #a b Pab H; nnormalize; /2/;
198##] nqed.
199
Note: See TracBrowser for help on using the repository browser.