[2570] | 1 | (**************************************************************************) |
---|
| 2 | (* ___ *) |
---|
| 3 | (* ||M|| *) |
---|
| 4 | (* ||A|| A project by Andrea Asperti *) |
---|
| 5 | (* ||T|| *) |
---|
| 6 | (* ||I|| Developers: *) |
---|
| 7 | (* ||T|| The HELM team. *) |
---|
| 8 | (* ||A|| http://helm.cs.unibo.it *) |
---|
| 9 | (* \ / *) |
---|
| 10 | (* \ / This file is distributed under the terms of the *) |
---|
| 11 | (* v GNU General Public License Version 2 *) |
---|
| 12 | (* *) |
---|
| 13 | (**************************************************************************) |
---|
| 14 | |
---|
| 15 | include "common/Errors.ma". |
---|
| 16 | include "common/IOMonad.ma". |
---|
| 17 | |
---|
| 18 | lemma option_bind_inverse : ∀A,B.∀m : option A.∀f : A → option B.∀r. |
---|
| 19 | ! x ← m ; f x = return r → |
---|
| 20 | ∃x.m = return x ∧ f x = return r. |
---|
| 21 | #A #B * normalize [2:#x] #f #r #EQ destruct |
---|
| 22 | %{x} %{EQ} % |
---|
| 23 | qed. |
---|
| 24 | |
---|
| 25 | lemma bind_option_inversion_star: |
---|
| 26 | ∀A,B: Type[0].∀P : Prop.∀f: option A. ∀g: A → option B. ∀y: B. |
---|
| 27 | (∀x.f = Some … x → g x = Some … y → P) → |
---|
| 28 | (! x ← f ; g x = Some … y) → P. |
---|
| 29 | #A #B #P #f #g #y #H #G elim (option_bind_inverse ????? G) #x * @H qed. |
---|
| 30 | |
---|
| 31 | interpretation "option bind inversion" 'bind_inversion = |
---|
| 32 | (bind_option_inversion_star ???????). |
---|
| 33 | |
---|
| 34 | lemma bind_inversion_star : ∀X,Y.∀P : Prop. |
---|
| 35 | ∀m : res X.∀f : X → res Y.∀v : Y. |
---|
| 36 | (∀x. m = return x → f x = return v → P) → |
---|
| 37 | ! x ← m ; f x = return v → P. |
---|
| 38 | #X #Y #P #m #f #v #H #G |
---|
| 39 | elim (bind_inversion ????? G) #x * @H qed. |
---|
| 40 | |
---|
| 41 | interpretation "res bind inversion" 'bind_inversion = |
---|
| 42 | (bind_inversion_star ???????). |
---|
| 43 | |
---|
| 44 | lemma IO_bind_inversion: |
---|
| 45 | ∀O,I,A,B.∀P : Prop.∀f: IO O I A. ∀g: A → IO O I B. ∀y: B. |
---|
| 46 | (∀x.f = return x → g x = return y → P) → |
---|
| 47 | (! x ← f ; g x = return y) → P. |
---|
| 48 | #O #I #A #B #P #f #g #y cases f normalize |
---|
| 49 | [ #o #f #_ #H destruct |
---|
| 50 | | #a #G #H @(G ? (refl …) H) |
---|
| 51 | | #e #_ #H destruct |
---|
| 52 | ] qed. |
---|
| 53 | |
---|
| 54 | interpretation "IO bind inversion" 'bind_inversion = |
---|
| 55 | (IO_bind_inversion ?????????). |
---|
| 56 | |
---|
| 57 | record MonadFunctRel (M1 : Monad) (M2 : Monad) : Type[1] ≝ |
---|
| 58 | { m_frel :6> ∀X,Y.∀P : X → Prop.(∀x.P x → Y) → (M1 X → M2 Y → Prop) |
---|
| 59 | ; mfr_return : ∀X,Y,P,F,x,prf.m_frel X Y P F (return x) (return (F x prf)) |
---|
| 60 | ; mfr_bind : ∀X,Y,Z,W,P,Q,F,G,m,n. |
---|
| 61 | m_frel X Y P F m n → ∀f,g.(∀x,prf.m_frel Z W Q G (f x) (g (F x prf))) → |
---|
| 62 | m_frel ?? Q G (m_bind … m f) (m_bind … n g) |
---|
| 63 | ; m_frel_ext : ∀X,Y,P,F,G.(∀x,prf1,prf2.F x prf1 = G x prf2) → ∀u,v.m_frel X Y P F u v → m_frel X Y P G u v |
---|
| 64 | }. |
---|
[2590] | 65 | |
---|
| 66 | record MonadFunctRel1 (M1 : Monad) (M2 : Monad) : Type[1] ≝ |
---|
| 67 | { m_frel1 :5> ∀X,Y.(Y → X) → (M1 X → M2 Y → Prop) |
---|
| 68 | ; mfr_return1 : ∀X,Y,F,y.m_frel1 X Y F (return (F y)) (return y) |
---|
| 69 | ; mfr_bind1 : ∀X,Y,Z,W,F,G,m,n. m_frel1 X Y F m n → |
---|
| 70 | ∀f,g.(∀x.m_frel1 Z W G (f (F x)) (g x)) → m_frel1 ?? G (m_bind … m f) (m_bind … n g) |
---|
| 71 | ; m_frel_ext1 : ∀X,Y,F,G.(∀x.F x = G x) → ∀ u,v.m_frel1 X Y F u v → m_frel1 X Y G u v |
---|
| 72 | }. |
---|
[2570] | 73 | |
---|
[2590] | 74 | |
---|
[2570] | 75 | definition res_preserve : MonadFunctRel Res Res ≝ |
---|
| 76 | mk_MonadFunctRel ?? |
---|
| 77 | (λX,Y,P,F,m,n.∀x.m = return x → ∃prf.n = return F x prf) |
---|
| 78 | ???. |
---|
| 79 | [ #X #Y #P #F #x #prf #x' whd in ⊢ (??%%→?); #EQ destruct(EQ) %{prf} % |
---|
| 80 | | #X #Y #Z #W #P #Q #F #G * |
---|
| 81 | [ #u | #e ] #n #H #f #g #K #x |
---|
| 82 | whd in ⊢ (??%%→?); #EQ destruct(EQ) |
---|
| 83 | cases (H ? (refl …)) #prf #L >L @(K ? prf ? EQ) |
---|
| 84 | | #X #Y #P #F #G #H #u #v #K #x #EQ |
---|
| 85 | cases (K … EQ) #prf #EQ' %{prf} >EQ' >H try % |
---|
| 86 | ] |
---|
| 87 | qed. |
---|
| 88 | |
---|
[2590] | 89 | definition res_preserve1 : MonadFunctRel1 Res Res ≝ |
---|
| 90 | mk_MonadFunctRel1 ?? |
---|
| 91 | (λX,Y,F,m,n.∀y.m = return y → ∃ x. n = return x ∧ y = F x) |
---|
| 92 | ???. |
---|
| 93 | [ #X #Y #F #y #x normalize #EQ destruct(EQ) %{y} % // |
---|
| 94 | | #X #Y #Z #W #F #G * [#x | #e] #n #H #f #g #H1 #z whd in ⊢ (??%% → ?); #EQ destruct |
---|
| 95 | cases(H x (refl …)) #y * #n_spec #x_spec |
---|
| 96 | cases(H1 y z ?) [2: <x_spec whd in ⊢ (???%); assumption] #w * #w_spec #z_spec %{w} |
---|
| 97 | >n_spec <w_spec % // |
---|
| 98 | | #X #Y #F #G #ext #u #v #K #x #u_spec cases(K x u_spec) #y * #v_spec #y_spec %{y} |
---|
| 99 | % // |
---|
| 100 | ] |
---|
| 101 | qed. |
---|
| 102 | |
---|
[2570] | 103 | definition opt_preserve : MonadFunctRel Option Option ≝ |
---|
| 104 | mk_MonadFunctRel ?? |
---|
| 105 | (λX,Y,P,F,m,n.∀x.m = return x → ∃prf.n = return F x prf) |
---|
| 106 | ???. |
---|
| 107 | [ #X #Y #P #F #x #prf #x' whd in ⊢ (??%%→?); #EQ destruct(EQ) %{prf} % |
---|
| 108 | | #X #Y #Z #W #P #Q #F #G * |
---|
| 109 | [ | #u ] #n #H #f #g #K #x |
---|
| 110 | whd in ⊢ (??%%→?); #EQ destruct(EQ) |
---|
| 111 | cases (H ? (refl …)) #prf #L >L @(K ? prf ? EQ) |
---|
| 112 | | #X #Y #P #F #G #H #u #v #K #x #EQ |
---|
| 113 | cases (K … EQ) #prf #EQ' %{prf} >EQ' >H try % |
---|
| 114 | ] |
---|
| 115 | qed. |
---|
| 116 | |
---|
[2590] | 117 | definition opt_preserve1 : MonadFunctRel1 Option Option ≝ |
---|
| 118 | mk_MonadFunctRel1 ?? |
---|
| 119 | (λX,Y,F,m,n.∀y.m = return y → ∃ x. n = return x ∧ y = F x) |
---|
| 120 | ???. |
---|
| 121 | [ #X #Y #F #y #x normalize #EQ destruct(EQ) %{y} % // |
---|
| 122 | | #X #Y #Z #W #F #G * [| #x] #n #H #f #g #H1 #z whd in ⊢ (??%% → ?); #EQ destruct |
---|
| 123 | cases(H x (refl …)) #y * #n_spec #x_spec |
---|
| 124 | cases(H1 y z ?) [2: <x_spec whd in ⊢ (???%); assumption] #w * #w_spec #z_spec %{w} |
---|
| 125 | >n_spec <w_spec % // |
---|
| 126 | | #X #Y #F #G #ext #u #v #K #x #u_spec cases(K x u_spec) #y * #v_spec #y_spec %{y} |
---|
| 127 | % // |
---|
| 128 | ] |
---|
| 129 | qed. |
---|
| 130 | |
---|
[2570] | 131 | definition io_preserve : ∀O,I.MonadFunctRel (IOMonad O I) (IOMonad O I) ≝ |
---|
| 132 | λO,I.mk_MonadFunctRel ?? |
---|
| 133 | (λX,Y,P,F,m,n.∀x.m = return x → ∃prf.n = return F x prf) |
---|
| 134 | ???. |
---|
| 135 | [ #X #Y #P #F #x #prf #x' whd in ⊢ (??%%→?); #EQ destruct(EQ) %{prf} % |
---|
| 136 | | #X #Y #Z #W #P #Q #F #G * |
---|
| 137 | [ #o #f | #u | #e ] #n #H #f #g #K #x |
---|
| 138 | whd in ⊢ (??%%→?); #EQ destruct(EQ) |
---|
| 139 | cases (H ? (refl …)) #prf #L >L @(K ? prf ? EQ) |
---|
| 140 | | #X #Y #P #F #G #H #u #v #K #x #EQ |
---|
| 141 | cases (K … EQ) #prf #EQ' %{prf} >EQ' >H try % |
---|
| 142 | ] |
---|
| 143 | qed. |
---|
| 144 | |
---|
[2590] | 145 | definition io_preserve1 : ∀O,I.MonadFunctRel1 (IOMonad O I) (IOMonad O I) ≝ |
---|
| 146 | λO,I.mk_MonadFunctRel1 ?? |
---|
| 147 | (λX,Y,F,m,n.∀y.m = return y → ∃ x. n = return x ∧ y = F x) |
---|
| 148 | ???. |
---|
| 149 | [ #X #Y #F #y #x normalize #EQ destruct(EQ) %{y} % // |
---|
| 150 | | #X #Y #Z #W #F #G * [#o #r | #x | #e] #n #H #f #g #H1 #z whd in ⊢ (??%% → ?); #EQ destruct |
---|
| 151 | cases(H x (refl …)) #y * #n_spec #x_spec |
---|
| 152 | cases(H1 y z ?) [2: <x_spec whd in ⊢ (???%); assumption] #w * #w_spec #z_spec %{w} |
---|
| 153 | >n_spec <w_spec % // |
---|
| 154 | | #X #Y #F #G #ext #u #v #K #x #u_spec cases(K x u_spec) #y * #v_spec #y_spec %{y} |
---|
| 155 | % // |
---|
| 156 | ] |
---|
| 157 | qed. |
---|
| 158 | |
---|
[2570] | 159 | definition preserving ≝ |
---|
| 160 | λM1,M2.λFR : MonadFunctRel M1 M2. |
---|
| 161 | λX,Y,A,B : Type[0]. |
---|
| 162 | λP : X → Prop. |
---|
| 163 | λQ : A → Prop. |
---|
| 164 | λF : ∀x : X.P x → Y. |
---|
| 165 | λG : ∀a : A.Q a → B. |
---|
| 166 | λf : X → M1 A. |
---|
| 167 | λg : Y → M2 B. |
---|
| 168 | ∀x,prf. |
---|
| 169 | FR … G |
---|
| 170 | (f x) (g (F x prf)). |
---|
| 171 | |
---|
[2590] | 172 | definition preserving1 ≝ |
---|
| 173 | λM1,M2.λFR : MonadFunctRel1 M1 M2. |
---|
| 174 | λX,Y,A,B : Type[0]. |
---|
| 175 | λF : Y → X. |
---|
| 176 | λG : B → A. |
---|
| 177 | λf : X → M1 A. |
---|
| 178 | λg : Y → M2 B. |
---|
| 179 | ∀ y. |
---|
| 180 | FR ?? G (f (F y)) (g y). |
---|
| 181 | |
---|
[2570] | 182 | definition preserving2 ≝ |
---|
| 183 | λM1,M2.λFR : MonadFunctRel M1 M2. |
---|
| 184 | λX,Y,Z,W,A,B : Type[0]. |
---|
| 185 | λP : X → Prop. |
---|
| 186 | λQ : Y → Prop. |
---|
| 187 | λR : A → Prop. |
---|
| 188 | λF : ∀x : X.P x → Z. |
---|
| 189 | λG : ∀y : Y.Q y → W. |
---|
| 190 | λH : ∀a : A.R a → B. |
---|
| 191 | λf : X → Y → M1 A. |
---|
| 192 | λg : Z → W → M2 B. |
---|
| 193 | ∀x,y,prf1,prf2. |
---|
| 194 | FR … H |
---|
| 195 | (f x y) (g (F x prf1) (G y prf2)). |
---|
[2590] | 196 | |
---|
| 197 | definition preserving21 ≝ |
---|
| 198 | λM1,M2.λFR : MonadFunctRel1 M1 M2. |
---|
| 199 | λX,Y,Z,W,A,B : Type[0]. |
---|
| 200 | λF : Z → X. |
---|
| 201 | λG : W → Y. |
---|
| 202 | λH : B → A. |
---|
| 203 | λf : X → Y → M1 A. |
---|
| 204 | λg : Z → W → M2 B. |
---|
| 205 | ∀z,w. FR ?? H (f (F z) (G w)) (g z w). |
---|
| 206 | |
---|
[2570] | 207 | lemma res_preserve_error : ∀X,Y,P,F,e,n.res_preserve X Y P F (Error … e) n. |
---|
| 208 | #X #Y #P #F #e #n #x whd in ⊢ (??%%→?); #EQ destruct(EQ) qed. |
---|
| 209 | |
---|
[2590] | 210 | lemma res_preserve_error1 : ∀X,Y,F,e,n.res_preserve1 X Y F (Error … e) n. |
---|
| 211 | #X #Y #F #e #n #x whd in ⊢ (??%%→?); #EQ destruct(EQ) qed. |
---|
| 212 | |
---|
[2570] | 213 | lemma mfr_return_eq : ∀M1,M2.∀FR : MonadFunctRel M1 M2. |
---|
| 214 | ∀X,Y,P,F,v,n. |
---|
| 215 | ∀prf.n = return F v prf → |
---|
| 216 | FR X Y P F (return v) n. |
---|
| 217 | #M1 #M2 #FR #X #Y #P #F #v #n #prf #EQ >EQ @mfr_return qed. |
---|
| 218 | |
---|
[2590] | 219 | lemma mfr_return_eq1 :∀M1,M2.∀FR : MonadFunctRel1 M1 M2. |
---|
| 220 | ∀X,Y,F,v,n. |
---|
| 221 | n = return F v → |
---|
| 222 | FR X Y F n (return v). |
---|
| 223 | #M1 #M2 #FR #X #Y #F #v #n #EQ >EQ @mfr_return1 |
---|
| 224 | qed. |
---|
| 225 | |
---|
[2570] | 226 | lemma opt_safe_eq : ∀A,m,x,prf.m = Some A x → opt_safe A m prf = x. |
---|
| 227 | #A #m #x #prf @opt_safe_elim #x' #EQ >EQ #EQ' destruct % qed. |
---|
| 228 | |
---|
| 229 | lemma opt_preserve_none : ∀X,Y,P,F,n.opt_preserve X Y P F (None ?) n. |
---|
| 230 | #X #Y #P #F #n #x whd in ⊢ (??%%→?); #EQ destruct(EQ) qed. |
---|
| 231 | |
---|
[2590] | 232 | lemma opt_preserve_none1 : ∀X,Y,F,n.opt_preserve1 X Y F (None ?) n. |
---|
| 233 | #X #Y #F #n #x whd in ⊢ (???% → ?); #EQ destruct qed. |
---|
| 234 | |
---|
[2570] | 235 | lemma m_list_map_All_ok : |
---|
| 236 | ∀M : MonadProps.∀X,Y,f,l. |
---|
| 237 | All X (λx.∃y.f x = return y) l → ∃l'.m_list_map M X Y f l = return l'. |
---|
| 238 | #M #X #Y #f #l elim l -l |
---|
| 239 | [ * %{[ ]} % |
---|
| 240 | | #hd #tl #IH * * #y #EQ #H cases (IH H) #ys #EQ' |
---|
| 241 | %{(y :: ys)} |
---|
| 242 | change with (! y ← ? ; ? = ?) |
---|
| 243 | >EQ >m_return_bind |
---|
| 244 | change with (! acc ← m_list_map ????? ; ? = ?) >EQ' |
---|
| 245 | @m_return_bind |
---|
| 246 | qed. |
---|
| 247 | |
---|
| 248 | lemma res_eq_from_opt : ∀A,m,a. |
---|
| 249 | res_to_opt A m = return a → m = return a. |
---|
| 250 | #A #m #a cases m #x normalize #EQ destruct(EQ) % |
---|
| 251 | qed. |
---|
| 252 | |
---|
| 253 | lemma res_to_opt_preserve : ∀X,Y,P,F,m,n. |
---|
| 254 | res_preserve X Y P F m n → opt_preserve X Y P F (res_to_opt … m) (res_to_opt … n). |
---|
| 255 | #X #Y #P #F #m #n #H #x #EQ |
---|
| 256 | cases (H x ?) |
---|
| 257 | [ #prf #EQ' %{prf} >EQ' % |
---|
| 258 | | cases m in EQ; normalize #x #EQ destruct % |
---|
| 259 | ] |
---|
| 260 | qed. |
---|
| 261 | |
---|
[2590] | 262 | lemma res_to_opt__preserve : ∀X,Y,F,m,n. |
---|
| 263 | res_preserve1 X Y F m n → opt_preserve1 X Y F (res_to_opt … m) (res_to_opt … n). |
---|
| 264 | #X #Y #F #m #n #H #x #EQ |
---|
| 265 | whd in H; cases (H x ?) |
---|
| 266 | [ #y * #y_spec #x_spec %{y} % [ >y_spec %|assumption] |
---|
| 267 | | cases m in EQ; normalize #x #EQ destruct % |
---|
| 268 | ] |
---|
| 269 | qed. |
---|
| 270 | |
---|
[2570] | 271 | lemma opt_to_res_preserve : ∀X,Y,P,F,m,n,e1,e2. |
---|
| 272 | opt_preserve X Y P F m n → |
---|
| 273 | res_preserve X Y P F (opt_to_res … e1 m) (opt_to_res … e2 n). |
---|
| 274 | #X #Y #P #F #m #n #e1 #e2 #H #v #prf |
---|
| 275 | cases (H … (opt_eq_from_res ???? prf)) #prf' #EQ %{prf'} |
---|
| 276 | >EQ % |
---|
| 277 | qed. |
---|
| 278 | |
---|
[2590] | 279 | lemma opt_to_res_preserve1 : ∀X,Y,F,m,n,e1,e2. |
---|
| 280 | opt_preserve1 X Y F m n → |
---|
| 281 | res_preserve1 X Y F (opt_to_res … e1 m) (opt_to_res … e2 n). |
---|
| 282 | #X #Y #F #m #n #e1 #e2 #H #x #EQ |
---|
| 283 | cases(H x ?) |
---|
| 284 | [ #y * #y_spec #x_spec %{y} % [>y_spec %|assumption] |
---|
| 285 | | cases m in EQ; normalize [2: #x1] #EQ destruct % |
---|
| 286 | ] |
---|
| 287 | qed. |
---|
| 288 | |
---|
[2570] | 289 | lemma err_eq_from_io : ∀O,I,X,m,v. |
---|
| 290 | err_to_io O I X m = return v → m = return v. |
---|
| 291 | #O #I #X * #x #v normalize #EQ destruct % qed. |
---|
| 292 | |
---|
| 293 | lemma res_to_io_preserve : ∀O,I,X,Y,P,F,m,n. |
---|
| 294 | res_preserve X Y P F m n → |
---|
| 295 | io_preserve O I X Y P F m n. |
---|
| 296 | #O #I #X #Y #P #F #m #n #H #v #prf |
---|
| 297 | cases (H … (err_eq_from_io ????? prf)) #prf' #EQ %{prf'} |
---|
| 298 | >EQ % |
---|
| 299 | qed. |
---|
| 300 | |
---|
[2590] | 301 | lemma res_to_io_preserve1 : ∀O,I,X,Y,F,m,n. |
---|
| 302 | res_preserve1 X Y F m n → |
---|
| 303 | io_preserve1 O I X Y F m n. |
---|
| 304 | #O #I #X #Y #F #m #n #H #v #EQ cases(H v (err_eq_from_io ????? EQ)) |
---|
| 305 | #y * #y_spec #v_spec %{y} % // >y_spec % |
---|
| 306 | qed. |
---|