Zulip Chat Archive
Stream: Loom
Topic: Paper cuts
Shreyas Srinivas (Oct 30 2025 at 16:11):
I wrote the following #mwe which I think illustrates the kind of paper cuts I get stuck at for a while which I would think lean-auto could solve.
Shreyas Srinivas (Oct 30 2025 at 16:12):
import Auto
import Loom.MonadAlgebras.NonDetT.Extract
import Loom.MonadAlgebras.WP.Tactic
import Loom.MonadAlgebras.WP.DoNames'
import CaseStudies.Velvet.Std
import CaseStudies.TestingUtil
open PartialCorrectness DemonicChoice Lean.Elab.Term.DoNames
set_option auto.smt.trust true
set_option auto.smt true
set_option auto.smt.timeout 2
set_option auto.smt.solver.name "cvc5"
method swapIndex (mut a : Array Int) (i : ℕ) (j : ℕ)
return (a_swapped : Array Int)
require i < a.size
require j < a.size
ensures a_swapped.size = a.size
ensures ∀ k : ℕ, k < a_swapped.size → k ≠ i ∧ k ≠ j → a_swapped[k]! = a[k]!
ensures a_swapped[i]! = a[j]!
ensures a_swapped[j]! = a[i]!
do
let mut temp := a[i]!
a[i] := a[j]!
a[j] := temp
return a
prove_correct swapIndex by
loom_solve -- nothing done
grind
Shreyas Srinivas (Oct 30 2025 at 16:12):
CC : @George Pîrlea
Shreyas Srinivas (Oct 30 2025 at 16:13):
why is loom_solve failing here?
Shreyas Srinivas (Oct 30 2025 at 16:19):
Further, there doesn't seem to be a way to name the requires so that I can use them for correct indexing (within the def)
Shreyas Srinivas (Oct 30 2025 at 16:35):
I did manage to solve this manually btw:
prove_correct swapIndex by
loom_solve
all_goals {
simp [TArray.set, Array.setIfInBounds, require_1, require_2]
try grind
}
Vladimir Gladstein (Nov 07 2025 at 15:18):
@Shreyas Srinivas hey! Did you try running it with a new version of Loom? If not please run lake update. Now the default automation for Loom is grind.
Also, of you want to use SMT solver tactics , such as auto, please make sure that you have cvc5 installed on your PATH
Shreyas Srinivas (Nov 07 2025 at 15:19):
Hey I already have cvc5 on my path. I'll update now and try
Shreyas Srinivas (Nov 07 2025 at 15:20):
One thing I am missing is the ability to name and use the requires and ensures of a procedure call (inside another procedure). I understand that you are generating Anonymous names for these
Shreyas Srinivas (Nov 07 2025 at 15:23):
Example : if I call swapIndex from inside a (quicksort) partition function, I am not sure how I can get the postcondition for size out of the call
Vladimir Gladstein (Nov 07 2025 at 15:25):
Also it seems like you have a problem with your post-condition
when you write
ensures a_swapped[i]! = a[j]!
a_swapped refers to a modified array a. But in the same time, because you pass a as a mutable argument (mut a : Array Int), a in the post condition will be referring to a mutated version of a
Shreyas Srinivas (Nov 07 2025 at 15:26):
Initially I didn't have mut
Vladimir Gladstein (Nov 07 2025 at 15:26):
you can try the following spec
method swapIndex (mut a : Array Int) (i : ℕ) (j : ℕ)
return (a_swapped : Array Int)
require i < a.size
require j < a.size
ensures a_swapped.size = a.size
ensures ∀ k : ℕ, k < a_swapped.size → k ≠ i ∧ k ≠ j → a_swapped[k]! = a[k]!
ensures a_swapped[i]! = aOld[j]!
ensures a_swapped[j]! = aOld[i]!
do
let mut temp := a[i]!
a[i] := a[j]!
a[j] := temp
return a
Vladimir Gladstein (Nov 07 2025 at 15:28):
Shreyas Srinivas said:
Initially I didn't have
mut
If you don't have mut then you cannot modify a. So you either need to use mut and then refer to the old variable as aOld or remove mut and create a local mutable variable inside the method
Vladimir Gladstein (Nov 07 2025 at 15:30):
Shreyas Srinivas said:
One thing I am missing is the ability to name and use the
requires andensuresof a procedure call (inside another procedure). I understand that you are generating Anonymous names for these
That's right, we indeed do not support this feature. If you could create a GitHub issue for it, we will add it in a course of the week.
Shreyas Srinivas (Nov 07 2025 at 15:30):
I noticed that TArray is gone with this update and we now just use normal Lean Arrays. This is a nice change
Shreyas Srinivas (Nov 07 2025 at 15:31):
Ah I didn't know one could access the old name as aOld. This helps
Vladimir Gladstein (Nov 07 2025 at 15:31):
Yes, I am planning to do a bunch of other cosmetics changes soon!
Vladimir Gladstein (Nov 07 2025 at 15:34):
Shreyas Srinivas said:
Ah I didn't know one could access the old name as
aOld. This helps
You can refer to this documentation https://github.com/verse-lab/loom/blob/master/CaseStudies/Velvet/velvet_documentation.md
Last updated: Dec 20 2025 at 21:32 UTC