@@ -17,13 +17,13 @@ public import Std.Do.Triple
1717
1818Weakest-precondition interpretation of `FreeM F` programs through `Std.Do`'s
1919predicate-transformer monad `PredTrans ps`. The universal property of `FreeM` lifts any
20- effect handler `F ι → PredTrans ps ι` to a unique monad morphism `wpH H = liftM H`,
20+ effect handler `F ι → PredTrans ps ι` to a unique monad morphism `liftM H`,
2121so 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`
22+ `[FreeM.WP F ps]` instance plugs `FreeM F` into `Std.Do`'s `WP`/`WPMonad`/`Triple`
2323infrastructure.
2424
25- The WP's structural rules (`wpH_pure`, `wpH_bind`, …) are immediate from `liftM` being a monad
26- morphism; the adequacy theorem `wpH_ofInterp_eq_wp_liftM ` — that WP-via-handler agrees with
25+ The WP's structural rules are immediate from `liftM` being a monad morphism; the
26+ adequacy theorem `liftM_wp_eq_wp_liftM ` — that WP-via-handler agrees with
2727`Std.Do`'s WP of the `liftM` interpretation — is the same statement of uniqueness.
2828
2929The design follows [Vistrup, Sammler, Jung. *Program Logics à la Carte.* POPL 2025], adapted
@@ -42,85 +42,33 @@ namespace FreeM
4242
4343universe u v w
4444
45- variable {F G : Type u → Type v} {ps : PostShape.{u}} {α β : Type u}
45+ variable {F : Type u → Type v} {ps : PostShape.{u}} {α β : Type u}
4646
47- /-- A logical handler: an effect handler from `F` into the predicate-transformer monad
48- `PredTrans ps`. -/
49- abbrev LHandler (F : Type u → Type v) (ps : PostShape.{u}) : Type (max (u + 1 ) v) :=
50- ∀ {ι : Type u}, F ι → PredTrans ps ι
51-
52- namespace LHandler
53-
54- /-- Sum of handlers; the counterpart of the paper's `H₁ ⊕ H₂`. -/
55- def sum (H₁ : LHandler F ps) (H₂ : LHandler G ps) :
56- LHandler (fun α => F α ⊕ G α) ps :=
57- fun op => Sum.elim H₁ H₂ op
58-
59- @[simp] theorem sum_inl (H₁ : LHandler F ps) (H₂ : LHandler G ps)
60- {ι : Type u} (x : F ι) :
61- LHandler.sum H₁ H₂ (Sum.inl x : F ι ⊕ G ι) = H₁ x := rfl
62-
63- @[simp] theorem sum_inr (H₁ : LHandler F ps) (H₂ : LHandler G ps)
64- {ι : Type u} (y : G ι) :
65- LHandler.sum H₁ H₂ (Sum.inr y : F ι ⊕ G ι) = H₂ y := rfl
66-
67- /-- Derive a logical handler from an effect handler into any `[WP m ps]` monad, by composing
68- with `m`'s WP. -/
69- def ofInterp {m : Type u → Type w} [WP m ps]
70- (interp : ∀ ι : Type u, F ι → m ι) : LHandler F ps :=
71- fun {ι} op => wp (interp ι op)
72-
73- @[simp] theorem ofInterp_apply {m : Type u → Type w} [WP m ps]
74- (interp : ∀ ι : Type u, F ι → m ι) {ι : Type u} (op : F ι) :
75- LHandler.ofInterp interp op = wp (interp ι op) := rfl
76-
77- end LHandler
78-
79- /-- Weakest-precondition interpretation of a `FreeM F α` program against a logical handler `H`.
80- Defined as `FreeM.liftM` instantiated at `PredTrans ps`, the unique monad morphism
81- `FreeM F → PredTrans ps` extending `H` per the universal property of `FreeM`. -/
82- def wpH (H : LHandler F ps) (x : FreeM F α) : PredTrans ps α :=
83- x.liftM H
84-
85- @[simp] theorem wpH_pure (H : LHandler F ps) (a : α) :
86- wpH H (pure a : FreeM F α) = Pure.pure a := rfl
87-
88- @[simp] theorem wpH_liftBind (H : LHandler F ps) {ι : Type u}
89- (op : F ι) (k : ι → FreeM F α) :
90- wpH H (lift op >>= k) = H op >>= fun x => wpH H (k x) := rfl
91-
92- @[simp] theorem wpH_lift (H : LHandler F ps) {ι : Type u} (op : F ι) :
93- wpH H (lift op : FreeM F ι) = H op :=
94- liftM_lift _ op
95-
96- @[simp] theorem wpH_bind (H : LHandler F ps) (x : FreeM F α) (f : α → FreeM F β) :
97- wpH H (x >>= f) = wpH H x >>= fun a => wpH H (f a) :=
98- liftM_bind _ x f
99-
100- /-- Adequacy theorem: WP via `FreeM` against an `ofInterp`-derived handler agrees with
47+ /-- Adequacy theorem: WP via `FreeM` against a WP-derived handler agrees with
10148`Std.Do`'s WP of the `liftM` interpretation. Equivalently, two monad morphisms
10249`FreeM F → PredTrans ps` extending the same handler are equal. -/
103- theorem wpH_ofInterp_eq_wp_liftM
104- {m : Type u → Type w} [Monad m] [LawfulMonad m] [ WPMonad m ps]
50+ theorem liftM_wp_eq_wp_liftM
51+ {m : Type u → Type w} [Monad m] [WPMonad m ps]
10552 (interp : ∀ ι : Type u, F ι → m ι) (x : FreeM F α) :
106- wpH (LHandler.ofInterp interp) x = wp (x.liftM (fun {_} => interp _)) := by
53+ x.liftM (fun {ι} op => wp (interp ι op)) =
54+ wp (x.liftM (fun {_} => interp _)) := by
10755 induction x with
108- | pure a => simp [wpH, FreeM.liftM, WPMonad.wp_pure]
56+ | pure a => simp [WPMonad.wp_pure]
10957 | lift_bind op k ih =>
11058 simp [WPMonad.wp_bind, ih]
11159
11260/-- Records a default logical handler for `F` at shape `ps`, enabling the global
11361`WP (FreeM F) ps` instance and any `Triple`/`mvcgen` reasoning over `FreeM F`. -/
114- class HasHandler (F : Type u → Type v) (ps : outParam (PostShape.{u})) where
62+ class WP (F : Type u → Type v) (ps : outParam (PostShape.{u})) where
11563 /-- The default logical handler for `F`. -/
11664 handler {ι : Type u} : F ι → PredTrans ps ι
11765
118- instance instWPFreeM [HasHandler F ps] : WP (FreeM F) ps where
119- wp := wpH HasHandler .handler
66+ instance instStdDoWP [WP F ps] : Std.Do. WP (FreeM F) ps where
67+ wp x := x.liftM WP .handler
12068
121- instance instWPMonadFreeM [HasHandler F ps] : WPMonad (FreeM F) ps where
69+ instance instWPMonadFreeM [WP F ps] : WPMonad (FreeM F) ps where
12270 wp_pure _ := rfl
123- wp_bind x f := wpH_bind _ x f
71+ wp_bind x f := liftM_bind _ x f
12472
12573end FreeM
12674
0 commit comments