Skip to content

Commit ce7a4f5

Browse files
authored
chore: add spec lemmas for MonadControl (#10544)
1 parent eb9dd9a commit ce7a4f5

File tree

2 files changed

+158
-0
lines changed

2 files changed

+158
-0
lines changed

src/Std/Do/Triple/SpecLemmas.lean

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,89 @@ theorem Spec.monadMap_trans [WP o ps] [MonadFunctor n o] [MonadFunctorT m n] :
181181
theorem Spec.monadMap_refl [WP m ps] :
182182
Triple (MonadFunctorT.monadMap f x : m α) (spred(wp⟦f x : m α⟧ Q)) spred(Q) := by simp [Triple]
183183

184+
/-! # `MonadControl` -/
185+
186+
@[spec]
187+
theorem Spec.liftWith_StateT [Monad m] [WPMonad m ps]
188+
(f : (∀{β}, StateT σ m β → m (β × σ)) → m α) :
189+
Triple
190+
(MonadControl.liftWith (m:=m) f)
191+
(fun s => wp⟦f (fun x => x.run s)⟧ (fun a => Q.1 a s, Q.2))
192+
Q := by simp [Triple]
193+
194+
@[spec]
195+
theorem Spec.liftWith_ReaderT [Monad m] [WPMonad m ps]
196+
(f : (∀{β}, ReaderT ρ m β → m β) → m α) :
197+
Triple
198+
(MonadControl.liftWith (m:=m) f)
199+
(fun s => wp⟦f (fun x => x.run s)⟧ (fun a => Q.1 a s, Q.2))
200+
Q := by simp [Triple]
201+
202+
@[spec]
203+
theorem Spec.liftWith_ExceptT [Monad m] [WPMonad m ps]
204+
(f : (∀{β}, ExceptT ε m β → m (Except ε β)) → m α) :
205+
Triple (ps := .except ε ps)
206+
(MonadControl.liftWith (m:=m) f)
207+
(wp⟦f (fun x => x.run)⟧ (Q.1, Q.2.2))
208+
Q := by simp [Triple]
209+
210+
@[spec]
211+
theorem Spec.restoreM_StateT [Monad m] [WPMonad m ps] (x : m (α × σ)) :
212+
Triple
213+
(MonadControl.restoreM x : StateT σ m α)
214+
(fun _ => wp⟦x⟧ (fun (a, s) => Q.1 a s, Q.2))
215+
Q := by simp [Triple]
216+
217+
@[spec]
218+
theorem Spec.restoreM_ReaderT [Monad m] [WPMonad m ps] (x : m α) :
219+
Triple (m := ReaderT ρ m)
220+
(MonadControl.restoreM (m:=m) x)
221+
(fun s => wp⟦x⟧ (fun a => Q.1 a s, Q.2))
222+
Q := by simp [Triple]
223+
224+
@[spec]
225+
theorem Spec.restoreM_ExceptT [Monad m] [WPMonad m ps] (x : m (Except ε α)) :
226+
Triple (ps := .except ε ps)
227+
(MonadControl.restoreM x : ExceptT ε m α)
228+
(wp⟦x⟧ (fun | .ok a => Q.1 a | .error e => Q.2.1 e, Q.2.2))
229+
Q := by simp [Triple]; rfl
230+
231+
/-! # `MonadControlT` -/
232+
233+
@[spec]
234+
theorem Spec.liftWith_trans [WP o ps] [MonadControl n o] [MonadControlT m n]
235+
(f : (∀{β}, o β → m (stM m o β)) → m α) :
236+
Triple (m:=o)
237+
(MonadControlT.liftWith (m:=m) f)
238+
(wp⟦MonadControl.liftWith (m:=n) fun x₂ => MonadControlT.liftWith fun x₁ => f (x₁ ∘ x₂) : o α⟧ Q)
239+
Q := .rfl
240+
241+
@[spec]
242+
theorem Spec.liftWith_refl [WP m ps] [Pure m]
243+
(f : (∀{β}, m β → m β) → m α) :
244+
Triple (m:=m)
245+
(MonadControlT.liftWith (m:=m) f)
246+
(wp⟦f (fun x => x) : m α⟧ Q)
247+
Q := .rfl
248+
249+
@[spec]
250+
theorem Spec.restoreM_trans [WP o ps] [MonadControl n o] [MonadControlT m n]
251+
(x : stM m o α) :
252+
Triple (m:=o)
253+
(MonadControlT.restoreM (m:=m) x)
254+
(wp⟦MonadControl.restoreM (m:=n) (MonadControlT.restoreM (m:=m) x) : o α⟧ Q)
255+
Q := .rfl
256+
257+
@[spec]
258+
theorem Spec.restoreM_refl [WP m ps] [Pure m]
259+
(x : stM m m α) :
260+
Triple (m:=m)
261+
(MonadControlT.restoreM (m:=m) x)
262+
(wp⟦Pure.pure x : m α⟧ Q)
263+
Q := .rfl
264+
265+
attribute [spec] controlAt control
266+
184267
/-! # `ReaderT` -/
185268

186269
attribute [spec] ReaderT.run

src/Std/Do/WP/SimpLemmas.lean

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,81 @@ theorem withTheReader_MonadWithReaderOf [MonadWithReaderOf ρ m] [WP m ps] (f :
281281

282282
end MonadFunctor
283283

284+
/-! ## `MonadControl`
285+
286+
The definitions that follow interpret `liftWith` and thus instances of, e.g., `MonadReaderWithOf`.
287+
288+
-/
289+
290+
section MonadControl
291+
292+
@[simp]
293+
theorem liftWith_StateT [Monad m] [WPMonad m ps]
294+
(f : (∀{β}, StateT σ m β → m (β × σ)) → m α) :
295+
wp⟦MonadControl.liftWith (m:=m) f⟧ Q = fun s => wp⟦f (fun x => x.run s)⟧ (fun a => Q.1 a s, Q.2) := by
296+
simp [MonadControl.liftWith, StateT.run]
297+
298+
@[simp]
299+
theorem liftWith_ReaderT [Monad m] [WPMonad m ps]
300+
(f : (∀{β}, ReaderT ρ m β → m β) → m α) :
301+
wp⟦MonadControl.liftWith (m:=m) f⟧ Q = fun s => wp⟦f (fun x => x.run s)⟧ (fun a => Q.1 a s, Q.2) := by
302+
simp [wp, MonadControl.liftWith, ReaderT.run]
303+
304+
@[simp]
305+
theorem liftWith_ExceptT [Monad m] [WPMonad m ps]
306+
(f : (∀{β}, ExceptT ε m β → m (Except ε β)) → m α) :
307+
wp⟦MonadControl.liftWith (m:=m) f⟧ Q = wp⟦f (fun x => x.run)⟧ (Q.1, Q.2.2) := by
308+
-- For some reason, the spec for `liftM` does not apply.
309+
simp [wp, MonadControl.liftWith, ExceptT.run, liftM, monadLift, MonadLift.monadLift, ExceptT.lift, ExceptT.mk]
310+
311+
@[simp]
312+
theorem liftWith_trans [WP o ps] [MonadControl n o] [MonadControlT m n]
313+
(f : (∀{β}, o β → m (stM m o β)) → m α) :
314+
wp⟦MonadControlT.liftWith f : o α⟧ Q = wp⟦MonadControl.liftWith (m:=n) fun x₂ => MonadControlT.liftWith fun x₁ => f (x₁ ∘ x₂) : o α⟧ Q := rfl
315+
316+
@[simp]
317+
theorem liftWith_refl [WP m ps] [Pure m]
318+
(f : (∀{β}, m β → m β) → m α) :
319+
wp⟦MonadControlT.liftWith (m:=m) f : m α⟧ Q = wp⟦f (fun x => x) : m α⟧ Q := rfl
320+
321+
@[simp]
322+
theorem restoreM_StateT [Monad m] [WPMonad m ps] (x : m (α × σ)) :
323+
wp⟦MonadControl.restoreM (m:=m) x : StateT σ m α⟧ Q = fun _ => wp⟦x⟧ (fun (a, s) => Q.1 a s, Q.2) := by
324+
simp [MonadControl.restoreM]
325+
326+
@[simp]
327+
theorem restoreM_ReaderT [Monad m] [WPMonad m ps] (x : m α) :
328+
wp⟦MonadControl.restoreM (m:=m) x : ReaderT ρ m α⟧ Q = fun s => wp⟦x⟧ (fun a => Q.1 a s, Q.2) := by
329+
simp [wp, MonadControl.restoreM]
330+
331+
@[simp]
332+
theorem restoreM_ExceptT [Monad m] [WPMonad m ps] (x : m (Except ε α)) :
333+
wp⟦MonadControl.restoreM (m:=m) x : ExceptT ε m α⟧ Q = wp⟦x⟧ (fun | .ok a => Q.1 a | .error e => Q.2.1 e, Q.2.2) := by
334+
simp [wp, MonadControl.restoreM]
335+
congr
336+
ext
337+
split <;> rfl
338+
339+
@[simp]
340+
theorem restoreM_trans [WP o ps] [MonadControl n o] [MonadControlT m n] (x : stM m o α) :
341+
wp⟦MonadControlT.restoreM x : o α⟧ Q = wp⟦MonadControl.restoreM (m:=n) (MonadControlT.restoreM (m:=m) x) : o α⟧ Q := rfl
342+
343+
@[simp]
344+
theorem restoreM_refl [Pure m] [WP m ps] (x : stM m m α) :
345+
wp⟦MonadControlT.restoreM x : m α⟧ Q = wp⟦Pure.pure x : m α⟧ Q := rfl
346+
347+
@[simp]
348+
theorem controlAt_MonadControlT [Bind n] [WP n ps] [MonadControlT m n]
349+
(f : (∀{β}, n β → m (stM m n β)) → m (stM m n α)) :
350+
wp⟦controlAt m f⟧ Q = wp⟦liftWith f >>= restoreM⟧ Q := rfl
351+
352+
@[simp]
353+
theorem control_MonadControlT [Bind n] [WP n ps] [MonadControlT m n]
354+
(f : (∀{β}, n β → m (stM m n β)) → m (stM m n α)) :
355+
wp⟦control f⟧ Q = wp⟦liftWith f >>= restoreM⟧ Q := rfl
356+
357+
end MonadControl
358+
284359
/-! ## `MonadExceptOf`
285360
286361
The definitions that follow interpret `throw`, `throwThe`, `tryCatch`, etc.

0 commit comments

Comments
 (0)