source: src/common/IOMonad.ma @ 3367

Last change on this file since 3367 was 2453, checked in by tranquil, 7 years ago

come changes in monad notation to

  • avoid pretty printed monsters
  • avoid "»=" notation for bind that breaks stuff like «?, ?» = ?
File size: 15.1 KB
RevLine 
[700]1include "utilities/extralib.ma".
2include "common/Errors.ma".
[24]3
4(* IO monad *)
5
[487]6inductive IO (output:Type[0]) (input:output → Type[0]) (T:Type[0]) : Type[0] ≝
[366]7| Interact : ∀o:output. (input o → IO output input T) → IO output input T
8| Value : T → IO output input T
[797]9| Wrong : errmsg → IO output input T.
[24]10
[1640]11include "utilities/proper.ma".
12(* a weak form of extensionality *)
13axiom interact_proper :
14  ∀O,I,T,o.∀f,g : I o → IO O I T.(∀i. f i = g i) → Interact … o f = Interact … o g.
15
[487]16let rec bindIO (O:Type[0]) (I:O → Type[0]) (T,T':Type[0]) (v:IO O I T) (f:T → IO O I T') on v : IO O I T' ≝
[24]17match v with
[366]18[ Interact out k ⇒ (Interact ??? out (λres. bindIO O I T T' (k res) f))
[24]19| Value v' ⇒ (f v')
[797]20| Wrong m ⇒ Wrong O I T' m
[24]21].
22
[1640]23include "utilities/monad.ma".
[24]24
[1640]25definition IOMonad ≝ λO,I.
[1647]26  MakeMonadProps
[1640]27  (* the monad *)
28  (IO O I)
29  (* return *)
30  (λX.Value … X)
31  (* bind *)
32  (bindIO O I)
[1882]33  ????. / by /
[1647]34[(* bind_ret *)
35 #X#m elim m normalize // #o#f#Hi @interact_proper //
36|(* bind_bind *)
[1640]37 #X#Y#Z#m#f#g elim m normalize [2,3://]
38 (* Interact *)
39  #o#f #Hi @interact_proper //
[1882]40|#X #Y #m #f #g #H elim m normalize
41  [ #o #x @interact_proper ] //
[1640]42]
43qed.
44
45definition bindIO2 ≝ λO,I. m_bind2 (IOMonad O I).
46
47include "hints_declaration.ma".
[1949]48alias symbol "hint_decl" (instance 1) = "hint_decl_Type1".
[1640]49unification hint 0 ≔ O, I, T;
[1882]50  N ≟ IOMonad O I, M ≟ max_def N
[1640]51(*******************************************) ⊢
[1882]52  IO O I T ≡ monad M T
[1640]53.
54
[1949]55let rec rel_io O I A B (Perr : relation errmsg) (P : A → B → Prop) (v1 : IO O I A)
56  (v2 : IO O I B) on v1 : Prop ≝
57  match v1 with
58  [ Value x ⇒
59    match v2 with
60    [ Value y ⇒
61      P x y
62    | _ ⇒ False
63    ]
64  | Wrong e1 ⇒
65    match v2 with
66    [ Wrong e2 ⇒ Perr e1 e2
67    | _ ⇒ False
68    ]
69  | Interact o1 f1 ⇒
70    match v2 with
71    [ Interact o2 f2 ⇒
72      ∃prf:o1 = o2.∀i.rel_io … Perr P (f1 i) (f2 ?)
73    | _ ⇒ False
74    ]
75  ]. <prf @i qed.
[1640]76
[1949]77definition IORel ≝ λO,I,Perr.
78  mk_MonadRel (IOMonad O I) (IOMonad O I)
79    (λA,B.rel_io O I A B Perr)
80    ???.
81[//
82|#X #Y #Z #W #relin #relout #m elim m
83  [ #o #f #IH * [#o' #f' | #v | #e] * #EQ destruct(EQ) #G
84    #f1 #f2 #G' whd %{(refl …)} #i
85    @(IH … (G i) f1 f2 G')
86  | #v * [#o #f * | #v' | #e *]
87    #Pvv' #f #g #H normalize @H @Pvv'
88  | #e1 * [#o #f * | #v' *| #e2] //
89  ]
90| #X #Y #P #Q #H #m elim m [#o #f #IH | #v | #e] *
91  [1,4,7: #o' #f' [2,3: *]
92    normalize * #prf destruct(prf) normalize #G
93    % [%] normalize #i @IH @G
94  |2,5,8: #v' [1,3: *]
95    @H
96  |*: #e' [1,2: *] //
97  ]
98]
99qed.
100
101lemma IORel_refl : ∀O,I,Perr.reflexive ? Perr → ∀X,rel.reflexive X rel →
102  reflexive ? (m_rel ?? (IORel O I Perr) ?? rel).
103#O #I #Perr #G #X #rel #H #m elim m
104[ #o #f #IH whd %[%] #i normalize @IH
105| #v @H
106| #e @G
107]
108qed.
109
110lemma IORel_transitive : ∀O,I,Perr1,Perr2,Perr3.
111  (∀e1,e2,e3.Perr1 e1 e2 → Perr2 e2 e3 → Perr3 e1 e3) →
112  ∀X,Y,Z,rel1,rel2,rel3.
113  (∀x : X.∀y : Y.∀z : Z.rel1 x y → rel2 y z → rel3 x z) →
114  ∀m,n,o.
115  m_rel ?? (IORel O I Perr1) … rel1 m n →
116  m_rel ?? (IORel O I Perr2) … rel2 n o →
117  m_rel ?? (IORel O I Perr3) … rel3 m o.
118#O #I #Perr1 #Perr2 #Perr3 #Herr #X #Y #Z #rel1 #rel2 #rel3 #H #m elim m
119[ #o #f #IH * [#o' #f' * [#o'' #f'' | #v #_ * | #e #_ * ] | #v #x * | #e #x * ]
120  normalize * #EQ #H1 * #EQ' #H2 destruct %[%] normalize #i @(IH ? (f' i)) //
121| #v * [#o #f #x * | #v' * [#o #f #_ * | #v'' |#e #_ *] | #e #x *]
122  @H
123| #e * [#o #f #x * | #v #x * | #e' * [#o #f #_ * | #v #_ * | #e'']] @Herr
124]
125qed.
126
127
128lemma rel_io_eq : ∀O,I,A.∀m,n:IO O I A.m = n → m_rel ?? (IORel O I (eq ?)) … (eq ?) m n.
129#O#I#A#m#n#EQ >EQ @IORel_refl //
130qed.
131
132lemma eq_rel_io : ∀O,I,A.∀m,n:IO O I A.m_rel ?? (IORel O I (eq ?)) … (eq ?) m n → m = n.
133#O#I#A#m elim m
134[ #o #f #IH * [#o' #f' | #v * | #e * ]
135  normalize * #EQ #H destruct @interact_proper #i @IH @H
136| #v * [#o #f * | #v' | #e *]
137| #e * [#o #f * | #v * | #e']
138] #EQ >EQ %
139qed.
140
141coercion rel_io_to_eq nocomposites : ∀O,I,A,m,n.∀prf : m = n.
142m_rel ?? (IORel O I (eq ?)) A A (eq ?) m n ≝ rel_io_eq on
143  _prf : eq (IO ???) ?? to m_rel ?? (IORel ?? (eq ?)) ?? (eq ?) ??.
144
145coercion eq_to_rel_io nocomposites : ∀O,I,A,m,n.∀prf :
146m_rel ?? (IORel O I (eq ?)) A A (eq ?) m n.m = n ≝ eq_rel_io on
147  _prf : m_rel ?? (IORel ?? (eq ?)) ?? (eq ?) ?? to eq (IO ???) ??.
148
149
150let rec pred_io O I A (Perr : predicate errmsg) (P : A → Prop) (v : IO O I A) on v : Prop ≝
151  match v with
152  [ Value x ⇒ P x
153  | Wrong e ⇒ Perr e
154  | Interact o f ⇒ ∀i.pred_io … Perr P (f i)
155  ].
156
157let rec pred_io_inject O I A Perr P (a : IO O I A)
158  on a : pred_io O I A Perr P a → IO O I (Σx.P x) ≝
159  match a return λx.pred_io O I A Perr P x → IO O I (Σx.P x) with
160  [ Interact o f ⇒ λprf.
161    Interact … o (λx.pred_io_inject … Perr P (f x) (prf x))
162  | Value x ⇒ λprf.return «x, prf»
163  | Wrong e ⇒ λ_.Wrong … e
164  ].
165
166definition IOPred ≝ λO,I,Perr.
[1976]167  mk_InjMonadPred (IOMonad O I)
168    (mk_MonadPred ? (λA.pred_io O I A Perr) ???)
[1949]169    (λA,P,a_sig.match a_sig with [ mk_Sig a prf ⇒ pred_io_inject O I A Perr P a prf ])
[1976]170    ?. //
171[ #X #P #Q #H #m elim m
172  [#o #f #IH #H #i @IH @H
173  | #v @H
174  | #e //
175  ]
176| #X #Y #relin #relout #m elim m
[1949]177  [ #o #f #IH whd in ⊢ (%→?); #H
178    #f #G whd #i
179    @(IH … (H i) f G)
180  | #v #Pv #f #H normalize @H @Pv
181  | #e //
182  ]
[1976]183| #X #P * #m elim m
[1949]184  [ #o #f #IH whd in ⊢ (%→?); #H
185    change with (Interact ?????) in ⊢ (???%);
186    @interact_proper #i
187    @(IH i (H i))
188  |*: //
189]
190qed.
191
192unification hint 0 ≔ O, I, Perr, A, P, v;
193M ≟ IOMonad O I, Pr ≟ IOPred O I Perr
194⊢ pred_io O I A Perr P v ≡ m_pred M Pr A P v.
195
[487]196definition err_to_io : ∀O,I,T. res T → IO O I T ≝
[797]197λO,I,T,v. match v with [ OK v' ⇒ Value O I T v' | Error m ⇒ Wrong O I T m ].
[1640]198
[487]199coercion err_to_io : ∀O,I,A.∀c:res A.IO O I A ≝ err_to_io on _c:res ? to IO ???.
[1640]200
[1976]201(*
[1949]202lemma res_io_pred : ∀O,I,A,Perr,P.∀m : res A.pred_res … Perr P m → pred_io O I ? Perr P m.
203#O #I #A #Perr #P * /2/ qed.
204
205lemma io_res_pred : ∀O,I,A,Perr,P.∀m : res A.pred_io O I ? Perr P m → pred_res ? Perr P m.
206#O #I #A #Perr #P * /2/ qed.
[1976]207*)
[487]208definition err_to_io_sig : ∀O,I,T.∀P:T → Prop. res (Sig T P) → IO O I (Sig T P) ≝
[797]209λO,I,T,P,v. match v with [ OK v' ⇒ Value O I (Sig T P) v' | Error m ⇒ Wrong O I (Sig T P) m ].
[487]210(*coercion err_to_io_sig : ∀O,I,A.∀P:A → Prop.∀c:res (Sig A P).IO O I (Sig A P) ≝ err_to_io_sig on _c:res (Sig ??) to IO ?? (Sig ??).*)
[24]211
[487]212let rec P_io O I (A:Type[0]) (P:A → Prop) (v:IO O I A) on v : Prop ≝
[24]213match v return λ_.Prop with
[797]214[ Wrong _ ⇒ True
[24]215| Value z ⇒ P z
[366]216| Interact out k ⇒ ∀v'.P_io O I A P (k v')
[24]217].
218
[487]219let rec P_io' O I (A:Type[0]) (P:A → Prop) (v:IO O I A) on v : Prop ≝
[24]220match v return λ_.Prop with
[797]221[ Wrong _ ⇒ False
[24]222| Value z ⇒ P z
[366]223| Interact out k ⇒ ∀v'.P_io' O I A P (k v')
[24]224].
225
[487]226definition P_to_P_option_io : ∀O,I,A.∀P:A → Prop.option (IO O I A) → Prop ≝
[366]227  λO,I,A,P,a.match a with
[24]228   [ None ⇒ False
[366]229   | Some y ⇒ P_io O I A P y
[24]230   ].
231
[487]232let rec io_inject_0 O I (A:Type[0]) (P:A → Prop) (a:IO O I A) (p:P_io O I A P a) on a : IO O I (Sig A P) ≝
[366]233(match a return λa'.P_io O I A P a' → ? with
[797]234 [ Wrong m ⇒ λ_. Wrong O I ? m
[1601]235 | Value c ⇒ λp'. Value ??? (mk_Sig A P c p')
[366]236 | Interact out k ⇒ λp'. Interact ??? out (λv. io_inject_0 O I A P (k v) (p' v))
[211]237 ]) p.
[24]238
[487]239definition 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 (Sig A P) ≝
[366]240  λO,I,A.λP:A → Prop.λa:option (IO O I A).λp:P_to_P_option_io O I A P a.
[487]241  (match a return λa'.P_to_P_option_io O I A P a' → IO O I (Sig A P) with
[211]242   [ None ⇒ λp'.?
[366]243   | Some b ⇒ λp'. io_inject_0 O I A P b p'
[211]244   ]) p.
[487]245elim p'; qed.
[24]246
[487]247let rec io_eject O I (A:Type[0]) (P: A → Prop) (a:IO O I (Sig A P)) on a : IO O I A ≝
[24]248match a with
[797]249[ Wrong m ⇒ Wrong ??? m
[1601]250| Value b ⇒ match b with [ mk_Sig w p ⇒ Value ??? w]
[25]251| Interact out k ⇒ Interact ??? out (λv. io_eject ?? A P (k v))
[24]252].
253
[487]254coercion io_inject :
255  ∀O,I,A.∀P:A → Prop.∀a.∀p:P_to_P_option_io O I ? P a.IO O I (Sig A P) ≝ io_inject
256  on a:option (IO ???) to IO ?? (Sig ? ?).
257coercion io_eject : ∀O,I,A.∀P:A → Prop.∀c:IO O I (Sig A P).IO O I A ≝ io_eject
258  on _c:IO ?? (Sig ? ?) to IO ???.
[24]259
[797]260definition opt_to_io : ∀O,I,T.errmsg → option T → IO O I T ≝
261λO,I,T,m,v. match v with [ None ⇒ Wrong ?? T m | Some v' ⇒ Value ??? v' ].
[24]262
[487]263lemma sig_bindIO_OK: ∀O,I,A,B. ∀P:A → Prop. ∀P':B → Prop. ∀e:IO O I (Sig A P). ∀f:Sig A P → IO O I B.
[1601]264  (∀v:A. ∀p:P v. P_io O I ? P' (f (mk_Sig A P v p))) →
[487]265  P_io O I ? P' (bindIO O I (Sig A P) B e f).
266#O #I #A #B #P #P' #e #f elim e;
267[ #out #k #IH #IH' whd; #res @IH //;
268| #v0 elim v0; #v #Hv #IH whd; @IH
269| //;
270] qed.
[24]271
[487]272lemma sig_bindIO2_OK: ∀O,I,A,B,C. ∀P:(A×B) → Prop. ∀P':C → Prop. ∀e:IO O I (Sig (A×B) P). ∀f: A → B → IO O I C.
[366]273  (∀vA:A.∀vB:B. ∀p:P 〈vA,vB〉. P_io O I ? P' (f vA vB)) →
274  P_io O I ? P' (bindIO2 O I A B C e f).
[487]275#I #O #A #B #C #P #P' #e #f elim e;
276[ #out #k #IH #IH' whd; #res @IH @IH'
277| #v0 elim v0; #v elim v; #vA #vB #Hv #IH @IH //;
278| //;
279] qed.
[24]280
[797]281lemma opt_bindIO_OK: ∀O,I,A,B,m. ∀P:B → Prop. ∀e:option A. ∀f: A → IO O I B.
[366]282  (∀v:A. e = Some A v → P_io O I ? P (f v)) →
[797]283  P_io O I ? P (bindIO O I A B (opt_to_io ??? m e) f).
284#I #O #A #B #m #P #e elim e; //; #v #f #H @H //;
[487]285qed.
[24]286
[797]287lemma opt_bindIO2_OK: ∀O,I,A,B,C,m. ∀P:C → Prop. ∀e:option (A×B). ∀f: A → B → IO O I C.
[366]288  (∀vA:A.∀vB:B. e = Some (A×B) 〈vA,vB〉 → P_io O I ? P (f vA vB)) →
[797]289  P_io O I ? P (bindIO2 O I A B C (opt_to_io ??? m e) f).
290#I #O #A #B #C #m #P #e elim e; //; #v cases v; #vA #vB #f #H @H //;
[487]291qed.
[125]292
[487]293lemma res_bindIO_OK: ∀O,I,A,B. ∀P:B → Prop. ∀e:res A. ∀f: A → IO O I B.
[366]294  (∀v:A. e = OK A v → P_io O I ? P (f v)) →
295  P_io O I ? P (bindIO O I A B e f).
[487]296#I #O #A #B #P #e elim e; //; #v #f #H @H //;
297qed.
[251]298
[487]299lemma res_bindIO2_OK: ∀O,I,A,B,C. ∀P:C → Prop. ∀e:res (A×B). ∀f: A → B → IO O I C.
[366]300  (∀vA:A.∀vB:B. e = OK (A×B) 〈vA,vB〉 → P_io O I ? P (f vA vB)) →
301  P_io O I ? P (bindIO2 O I A B C e f).
[487]302#I #O #A #B #C #P #e elim e; //; #v cases v; #vA #vB #f #H @H //;
303qed.
[251]304
[487]305lemma bindIO_OK: ∀O,I,A,B. ∀P:B → Prop. ∀e:IO O I A. ∀f: A → IO O I B.
[366]306  (∀v:A. P_io O I ? P (f v)) →
307  P_io O I ? P (bindIO O I A B e f).
[487]308#I #O #A #B #P #e elim e;
309[ #out #k #IH #f #H whd; #res @IH //;
310| #v #f #H @H
311| //;
312] qed.
[24]313
[487]314lemma bindIO2_OK: ∀O,I,A,B,C. ∀P:C → Prop. ∀e:IO O I (A×B). ∀f: A → B → IO O I C.
[366]315  (∀v1:A.∀v2:B. P_io O I ? P (f v1 v2)) →
316  P_io O I ? P (bindIO2 O I A B C e f).
[487]317#I #O #A #B #C #P #e elim e;
318[ #out #k #IH #f #H whd; #res @IH //;
319| #v cases v; #v1 #v2 #f #H @H
320| //;
321] qed.
[252]322
[487]323lemma P_bindIO_OK: ∀O,I,A,B. ∀P':A → Prop. ∀P:B → Prop. ∀e:IO O I A. ∀f: A → IO O I B.
[252]324  P_io … P' e →
[366]325  (∀v:A. P' v → P_io O I ? P (f v)) →
326  P_io O I ? P (bindIO O I A B e f).
[487]327#I #O #A #B #P' #P #e elim e;
[1647]328[ #out #k #IH #f #He #H whd in He ⊢ %; #res @IH /2 by /;
[487]329| #v #f #He #H @H @He
330| //;
331] qed.
[252]332
[487]333lemma 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.
[252]334  P_io … P' e →
[366]335  (∀v1:A.∀v2:B. P' 〈v1,v2〉 → P_io O I ? P (f v1 v2)) →
336  P_io O I ? P (bindIO2 O I A B C e f).
[487]337#I #O #A #B #C #P' #P #e elim e;
[1647]338[ #out #k #IH #f #He #H whd in He ⊢ %; #res @IH /2 by /;
[487]339| #v cases v; #v1 #v2 #f #He #H @H @He
340| //;
341] qed.
[252]342
343
[411]344(* Is there a way to prove this without extensionality? *)
[1640]345(*
[487]346lemma bind_assoc_r: ∀O,I,A,B,C,e,f,g.
347  ∀ext:(∀T1,T2:Type[0].∀f,f':T1 → T2.(∀x.f x = f' x) → f = f').
[411]348  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).
[487]349#O #I #A #B #C #e #f #g #ext elim e;
350[ #o #k #IH whd in ⊢ (??%%); @eq_f
351    @ext @IH
352| #v @refl
[797]353| #m @refl
[487]354] qed.
[1640]355*)
356definition bind_assoc_r ≝ λO,I.m_bind_bind (IOMonad O I).
[24]357
[487]358(*
359lemma 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.
[366]360  (∀a,b. eject ?? e = 〈a,b〉 → P 〈a,b〉 → P_io O I ? R (Q a b)) →
[487]361  P_io O I ? R (match eject ?? e with [ pair a b ⇒ Q a b ]).
362#I #O #A #B #C #P #e #Q #R cases e; #e' cases e'; normalize;
363[ *;
[1647]364| #e'' cases e''; #a #b #Pab #H normalize; /2 by _/;
[487]365] qed.
366*)
[1920]367
368(* Inversion when injecting errors into IO monad. *)
[2044]369lemma bind_res_value : ∀O,I,A,B,e,f,v. ∀P:B → Type[0].
[1920]370  (∀a. e = OK A a → f a = OK B v → P v) →
[2453]371  (match m_bind … e f  with [ OK v ⇒ Value … v | Error m ⇒ Wrong … m ] = Value O I B v → P v).
[1920]372#O #I #A #B *
373[ #a #f #v #P #H #E @H [ @a | @refl | normalize in E; cases (f a) in E ⊢ %;
374  [ #v' #E normalize in E; destruct @refl | #m #E normalize in E; destruct ] ]
375| #m #f #v #P #H #E whd in E:(??%?); destruct
376] qed.
377
[2044]378lemma bindIO_value : ∀O,I,A,B,e,f,v. ∀P:B → Type[0].
[1920]379  (∀a. e = Value ??? a → f a = Value ??? v → P v) →
380  (bindIO O I A B e f = Value ??? v → P v).
381#O #I #A #B *
382[ #o #k #f #v #P #H #E whd in E:(??%?); destruct
383| #a #f #v #P #H #E @H [ @a | @refl | @E ]
384| #m #f #v #P #H #E whd in E:(??%?); destruct
385] qed.
[1930]386
[2145]387lemma bindIO_res_interact : ∀O,I,A,B,e,f,o,k. ∀P:∀o:O. (I o → IO O I B) → Type[0].
388  (∀v. e = OK A v → f v = Interact … o k → P o k) →
389  bindIO O I A B (err_to_io … e) f = Interact … o k → P o k.
390#O #I #A #B *
391[ #a #f #o #k #P #H #E @(H … E) @refl
392| #m #f #o #k #P #_ #E whd in E:(??%?); destruct
393] qed.
394
395lemma bindIO_opt_interact : ∀O,I,A,B,m,e,f,o,k. ∀P:∀o:O. (I o → IO O I B) → Type[0].
396  (∀v. e = Some A v → f v = Interact … o k → P o k) →
397  bindIO O I A B (opt_to_io … m e) f = Interact … o k → P o k.
398#O #I #A #B #m *
399[ #f #o #k #P #_ #E whd in E:(??%?); destruct
400| #a #f #o #k #P #H #E @(H … E) @refl
401] qed.
402
[1930]403lemma bindIO_inversion: ∀O,I.
404  ∀A,B: Type[0]. ∀f: IO O I A. ∀g: A → IO O I B. ∀y: B.
[2453]405  (m_bind … f g = return y) →
[1930]406  ∃x. (f = return x) ∧ (g x = return y).
407#O #I #A #B #f #g #y cases f normalize
408[ #o #k #E destruct
409| #a #e %{a} /2 by conj/
410| #m #H destruct (H)
411] qed.
412
413(* When something in the error monad has found its way into the IO monad,
414   ensure that we can implicitly go back. *)
415lemma io_eq_to_res : ∀O,I. ∀T:Type[0]. ∀e:res T. ∀v.
416  err_to_io … e = Value O I T v →
417  e = OK T v.
418#O #I #T *
419[ #e #v #E normalize in E; destruct @refl
420| #m #v #E normalize in E; destruct
421]
422qed.
423
424coercion io_eq_from_res :
425  ∀O,I,T,e,v. ∀E:err_to_io O I T e = Value O I T v. e = OK T v ≝ io_eq_to_res
426  on _E:eq (IO ???) ?? to eq (res ?) ??.
427
[2444]428(* and for an unreduced form *)
429coercion io_monad_eq_from_res :
430  ∀O,I,T,e,v. ∀E:err_to_io O I T e = Value O I T v. e = OK T v ≝ io_eq_to_res
431  on _E:eq (monad (max_def (IOMonad ??)) ?) ?? to eq (res ?) ??.
432
[2428]433(* Similarly for opt *)
434
435lemma io_eq_to_opt : ∀O,I. ∀T:Type[0]. ∀e:option T. ∀m,v.
436  opt_to_io … m e = Value O I T v →
437  e = Some T v.
438#O #I #T *
439[ #m #v #E normalize in E; destruct
440| #t #m #v #E normalize in E; destruct %
441]
442qed.
443
444coercion io_eq_from_opt :
445  ∀O,I,T,e,m,v. ∀E:opt_to_io O I T m e = Value O I T v. e = Some T v ≝ io_eq_to_opt
446  on _E:eq (IO ???) ?? to eq (option ?) ??.
447
[2444]448coercion io_monad_eq_from_opt :
449  ∀O,I,T,e,m,v. ∀E:opt_to_io O I T m e = Value O I T v. e = Some T v ≝ io_eq_to_opt
450  on _E:eq (monad (max_def (IOMonad ??)) ?) ?? to eq (option ?) ??.
[2428]451
452
[2444]453
Note: See TracBrowser for help on using the repository browser.