Zulip Chat Archive
Stream: lean4
Topic: Applying post invariant to Hoare State Monad
Gary Haussmann (Mar 16 2022 at 16:16):
I'm working through "The Hoare State Monad" by Wouter Swierstra and have written up a Lean version:
-- Hoare logic pre and post invariants
def Pre (s : Type) : Type := s → Prop
def Post (s α : Type) : Type := s → α → s → Prop
-- Hoare Logic State monad returns a (s × α × post) structure
structure HLOut (s α : Type) (postCondition : Post s α) (stateIn : s) where
(stateOut : s) (retVal : α) (postInvariant : postCondition stateIn retVal stateOut)
-- state monad with pre/post invariants
def HLStateM (s : Type) (pre : Pre s) (α : Type) (post : Post s α) : Type :=
(s₁ : s) → (p : pre s₁) → HLOut s α post s₁
I'd like to move the monad result type α
to the end of the HLStateM
type so that I can make Functor and Monad instances:
def HLStateM (s : Type) (pre : Pre s) (post : Post s α) (α : Type) : Type :=
(s₁ : s) → (p : pre s₁) → HLOut s α post s₁
However, this is a problem since now the post invariant Post s α
shows up in the declaration earlier thanα
upon which it depends . In fact I think Lean makes a second α
instance specifically for Post s α
. Of course the two α
don't match so that's a no-go.
The natural solution is to remove the α
from Post s α
so that it only depends on the state s
but then I lose the ability to apply the invariant to the monad result α
. I'm not well-versed in dependent type programming so I thought to check here to see if there are any alternatives or useful tricks I could use here.
Simon Hudon (Mar 16 2022 at 20:27):
I think you should swap the two declarations (α : Type) (post : Post s α)
. It's annoying if you want (α : Type)
to be the last declaration because it's the output type of the monad but you can think of the output to be the pair (α, post)
. You could encode that in the types by combining α
and post
into post : { α : Type // Post s α }
but I would be careful going down that road because you risk intertwining the proof and the program definition.
Gary Haussmann (Mar 16 2022 at 22:04):
I know I can always just use raw bind or (>>=) but I would sad to lose do notation. I could just embed the postcondition into the output type HLOut
but that might make it difficult to infer types/proofs?
Simon Hudon (Mar 16 2022 at 22:29):
I don't think you can fit the Hoare state monad into Haskell-style monads. The good news is that the notation system in Lean 4 is very flexible and you can make adapted notation for your monads.
Last updated: Dec 20 2023 at 11:08 UTC