@@ -7,7 +7,6 @@ Authors: Tanner Duve
77module
88
99public import Cslib.Foundations.Control.Monad.Free
10- public import Cslib.Foundations.Control.Monad.Free.Effects
1110public import Std.Do.PredTrans
1211public import Std.Do.WP.Basic
1312public import Std.Do.WP.Monad
@@ -18,9 +17,9 @@ public import Std.Do.Triple
1817
1918Weakest-precondition interpretation of `FreeM F` programs through `Std.Do`'s
2019predicate-transformer monad `PredTrans ps`. The universal property of `FreeM` lifts any
21- effect handler `F ι → PredTrans ps ι` to a unique monad morphism `wpH H = liftM H.run `,
22- so weakest preconditions are compositional in `FreeM`'s monadic structure. An
23- `[LHandler F ps]` instance plugs `FreeM F` into `Std.Do`'s `WP`/`WPMonad`/`Triple`
20+ effect handler `F ι → PredTrans ps ι` to a unique monad morphism `wpH H = liftM H`,
21+ so weakest preconditions are compositional in `FreeM`'s monadic structure. A
22+ `[HasHandler F ps]` instance plugs `FreeM F` into `Std.Do`'s `WP`/`WPMonad`/`Triple`
2423infrastructure.
2524
2625The WP's structural rules (`wpH_pure`, `wpH_bind`, …) are immediate from `liftM` being a monad
@@ -47,52 +46,51 @@ variable {F G : Type u → Type v} {ps : PostShape.{u}} {α β : Type u}
4746
4847/-- A logical handler: an effect handler from `F` into the predicate-transformer monad
4948`PredTrans ps`. -/
50- structure LHandler (F : Type u → Type v) (ps : PostShape.{u}) : Type (max (u + 1 ) v) where
51- /-- The assignment from operations to predicate transformers. -/
52- run {ι : Type u} : F ι → PredTrans ps ι
49+ abbrev LHandler (F : Type u → Type v) (ps : PostShape.{u}) : Type (max (u + 1 ) v) :=
50+ ∀ {ι : Type u}, F ι → PredTrans ps ι
5351
5452namespace LHandler
5553
5654/-- Sum of handlers; the counterpart of the paper's `H₁ ⊕ H₂`. -/
5755def sum (H₁ : LHandler F ps) (H₂ : LHandler G ps) :
58- LHandler (fun α => F α ⊕ G α) ps where
59- run := Sum.elim H₁.run H₂.run
56+ LHandler (fun α => F α ⊕ G α) ps :=
57+ fun op => Sum.elim H₁ H₂ op
6058
61- @[simp] theorem sum_run_inl (H₁ : LHandler F ps) (H₂ : LHandler G ps)
59+ @[simp] theorem sum_inl (H₁ : LHandler F ps) (H₂ : LHandler G ps)
6260 {ι : Type u} (x : F ι) :
63- ( LHandler.sum H₁ H₂).run (Sum.inl x : F ι ⊕ G ι) = H₁.run x := rfl
61+ LHandler.sum H₁ H₂ (Sum.inl x : F ι ⊕ G ι) = H₁ x := rfl
6462
65- @[simp] theorem sum_run_inr (H₁ : LHandler F ps) (H₂ : LHandler G ps)
63+ @[simp] theorem sum_inr (H₁ : LHandler F ps) (H₂ : LHandler G ps)
6664 {ι : Type u} (y : G ι) :
67- ( LHandler.sum H₁ H₂).run (Sum.inr y : F ι ⊕ G ι) = H₂.run y := rfl
65+ LHandler.sum H₁ H₂ (Sum.inr y : F ι ⊕ G ι) = H₂ y := rfl
6866
6967/-- Derive a logical handler from an effect handler into any `[WP m ps]` monad, by composing
7068with `m`'s WP. -/
7169def ofInterp {m : Type u → Type w} [WP m ps]
72- (interp : ∀ ι : Type u, F ι → m ι) : LHandler F ps where
73- run {ι} op := wp (interp ι op)
70+ (interp : ∀ ι : Type u, F ι → m ι) : LHandler F ps :=
71+ fun {ι} op => wp (interp ι op)
7472
75- @[simp] theorem ofInterp_run {m : Type u → Type w} [WP m ps]
73+ @[simp] theorem ofInterp_apply {m : Type u → Type w} [WP m ps]
7674 (interp : ∀ ι : Type u, F ι → m ι) {ι : Type u} (op : F ι) :
77- ( LHandler.ofInterp interp).run op = wp (interp ι op) := rfl
75+ LHandler.ofInterp interp op = wp (interp ι op) := rfl
7876
7977end LHandler
8078
8179/-- Weakest-precondition interpretation of a `FreeM F α` program against a logical handler `H`.
8280Defined as `FreeM.liftM` instantiated at `PredTrans ps`, the unique monad morphism
8381`FreeM F → PredTrans ps` extending `H` per the universal property of `FreeM`. -/
8482def wpH (H : LHandler F ps) (x : FreeM F α) : PredTrans ps α :=
85- x.liftM ( fun {_} => H.run)
83+ x.liftM H
8684
8785@[simp] theorem wpH_pure (H : LHandler F ps) (a : α) :
8886 wpH H (pure a : FreeM F α) = Pure.pure a := rfl
8987
9088@[simp] theorem wpH_liftBind (H : LHandler F ps) {ι : Type u}
9189 (op : F ι) (k : ι → FreeM F α) :
92- wpH H (lift op >>= k) = H.run op >>= fun x => wpH H (k x) := rfl
90+ wpH H (lift op >>= k) = H op >>= fun x => wpH H (k x) := rfl
9391
9492@[simp] theorem wpH_lift (H : LHandler F ps) {ι : Type u} (op : F ι) :
95- wpH H (lift op : FreeM F ι) = H.run op :=
93+ wpH H (lift op : FreeM F ι) = H op :=
9694 liftM_lift _ op
9795
9896@[simp] theorem wpH_bind (H : LHandler F ps) (x : FreeM F α) (f : α → FreeM F β) :
@@ -115,7 +113,7 @@ theorem wpH_ofInterp_eq_wp_liftM
115113`WP (FreeM F) ps` instance and any `Triple`/`mvcgen` reasoning over `FreeM F`. -/
116114class HasHandler (F : Type u → Type v) (ps : outParam (PostShape.{u})) where
117115 /-- The default logical handler for `F`. -/
118- handler : LHandler F ps
116+ handler {ι : Type u} : F ι → PredTrans ps ι
119117
120118instance instWPFreeM [HasHandler F ps] : WP (FreeM F) ps where
121119 wp := wpH HasHandler.handler
@@ -124,52 +122,6 @@ instance instWPMonadFreeM [HasHandler F ps] : WPMonad (FreeM F) ps where
124122 wp_pure _ := rfl
125123 wp_bind x f := wpH_bind _ x f
126124
127- /-- Logical handler for the state effect, induced by `Std.Do`'s `WP (StateM σ)`. -/
128- def StateF.handler {σ : Type u} : LHandler (StateF σ) (.arg σ .pure) :=
129- LHandler.ofInterp (m := StateM σ) (fun _ op => FreeState.stateInterp op)
130-
131- instance StateF.instHasHandler {σ : Type u} :
132- HasHandler (StateF σ) (.arg σ .pure) where
133- handler := StateF.handler
134-
135- /-- WP of a `FreeState` program matches WP of its `StateM` interpretation. -/
136- theorem StateF.wp_FreeState_eq_wp_toStateM {σ : Type u} (comp : FreeState σ α) :
137- wp comp = wp (FreeState.toStateM comp) :=
138- wpH_ofInterp_eq_wp_liftM (m := StateM σ)
139- (fun _ op => FreeState.stateInterp op) comp
140-
141- /-- Hoare spec for `get` on `FreeState`. -/
142- @[spec]
143- theorem Spec.get_FreeState {σ : Type u} {Q : PostCond σ (.arg σ .pure)} :
144- Triple (MonadStateOf.get : FreeState σ σ) (spred(fun s => Q.1 s s)) Q := by
145- mvcgen
146-
147- /-- Hoare spec for `set` on `FreeState`. -/
148- @[spec]
149- theorem Spec.set_FreeState {σ : Type u} (s : σ) {Q : PostCond PUnit (.arg σ .pure)} :
150- Triple (MonadStateOf.set s : FreeState σ PUnit) (spred(fun _ => Q.1 ⟨⟩ s)) Q := by
151- mvcgen
152-
153- /-- Logical handler for the reader effect, induced by `Std.Do`'s `WP (ReaderM σ)`. -/
154- def ReaderF.handler {σ : Type u} : LHandler (ReaderF σ) (.arg σ .pure) :=
155- LHandler.ofInterp (m := ReaderM σ) (fun _ op => FreeReader.readInterp op)
156-
157- instance ReaderF.instHasHandler {σ : Type u} :
158- HasHandler (ReaderF σ) (.arg σ .pure) where
159- handler := ReaderF.handler
160-
161- /-- WP of a `FreeReader` program matches WP of its `ReaderM` interpretation. -/
162- theorem ReaderF.wp_FreeReader_eq_wp_toReaderM {σ : Type u} (comp : FreeReader σ α) :
163- wp comp = wp (FreeReader.toReaderM comp) :=
164- wpH_ofInterp_eq_wp_liftM (m := ReaderM σ)
165- (fun _ op => FreeReader.readInterp op) comp
166-
167- /-- Hoare spec for `read` on `FreeReader`. -/
168- @[spec]
169- theorem Spec.read_FreeReader {ρ : Type u} {Q : PostCond ρ (.arg ρ .pure)} :
170- Triple (MonadReaderOf.read : FreeReader ρ ρ) (spred(fun r => Q.1 r r)) Q := by
171- mvcgen
172-
173125end FreeM
174126
175127end Cslib
0 commit comments