Zulip Chat Archive
Stream: batteries
Topic: PR #1107 help needed with Satisfies
Shreyas Srinivas (Jan 31 2025 at 15:10):
Hello all, I need some help with working around this SatisfiesM
predicate in batteries#1107
This PR is about adding some missing monadic defs for vectors (see the discussion in batteries#925). I am trying to extract the size guarantee of Array.size_modifyM
(which uses Satisfies) to give me a proof that the size of the modified vector remains unchanged (around line 31). Conceptually I understand where my "proof" is going wrong. But I am not sure I know how to work around it.
Shreyas Srinivas (Jan 31 2025 at 16:27):
Update
On discord, we discussed using an [implemented_by]
unsafe def ... with an unsafe cast on
Array.modifyM to get a vector, and writing the safe version without using
Array` defs. User Rob_23oba (who is not on Zulip) suggested something as follows:
@[inline]
unsafe def modifyMUnsafe [Monad m] (v : Vector α n) (i : Nat) (f : α → m α) : m (Vector α n) :=
-- Array and Vector have the same internal representation, so this cast is valid
unsafeCast (Array.modifyM v.toArray i f)
/--
`modifyM v i f` applies a monadic transformation `f` to `v[i]`
-/
@[implemented_by modifyMUnsafe]
def modifyM [Monad m] (v : Vector α n) (i : Nat) (f : α → m α) : m (Vector α n) := do
if h : i < n then
let x := v[i]
let x ← f x
pure <| v.set i x
else
pure v
Shreyas Srinivas (Jan 31 2025 at 16:28):
The disadvantage is that of course one is always using the unsafe version for computations in practice.
Shreyas Srinivas (Jan 31 2025 at 16:29):
The advantage is that one doesn't need extra typeclass instances like LawfulMonad
, LawfulFunctor
and MonadSatisfying
to use satisfying
Shreyas Srinivas (Jan 31 2025 at 16:30):
What is the community's opinion on this? CC : @Kim Morrison
Kim Morrison (Jan 31 2025 at 20:39):
No unsafe definitions here please, unless there are significant performance gains which are otherwise in inaccessible. In particular, not for the sake of proofs.
Kim Morrison (Jan 31 2025 at 20:43):
Why do you want the implemented_by here in the first place?
Kim Morrison (Jan 31 2025 at 20:44):
Note that for Array/Vector I'll soon be changing the signature, so modify
takes an in-bounds proof and modifyIfInBounds
preserves the current behaviour parallel to List.
Shreyas Srinivas (Jan 31 2025 at 20:45):
It was an idea to get around the challenge I described above. I need to show that the size of the vector after modifyM
is n
and I have very little experience with SatisfiesM
Shreyas Srinivas (Jan 31 2025 at 20:47):
So to use the satisfying
function to extract the proof from Array.size_modifyM
, I had to add a bunch of instances and the proof is still wrong. I can see why it is wrong, but not the fix.
Kim Morrison (Jan 31 2025 at 20:47):
What's wrong with the safe definition above? Just remove the implemented by.
Shreyas Srinivas (Jan 31 2025 at 20:48):
It might not be efficient. Last time I wrote my own defs for Vector I was told that it must use the array functions.
Shreyas Srinivas (Jan 31 2025 at 20:50):
To make sure the functions use FBIP
Last updated: May 02 2025 at 03:31 UTC