vcgen: no spec found for a call through a structure projection `ops.op x` with `ops` a concrete instance
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 30/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- devtools
Research direction
Start from the standalone reproducer: prog calls ops.op x, and opImpl_spec is stated about opImpl x. Find where vcgen looks up a spec by the program's head symbol and why it does not unfold the structure projection of the concrete ops instance. Compare with the working spec_proj case. Done when the first example, sym => vcgen [prog, ops, opImpl_spec] <;> finish, closes without the "No spec found" error.
Written by the indexing model from the issue text.
Description
This issue was written by Claude (an AI assistant) on behalf of @nomeata.
Found while moving con-leche's cached-to-pure simulation proofs (a few thousand lines) to vcgen + grind (sym … => vcgen … <;> finish). Each case has a workaround in con-leche; the reproducer below is standalone.
vcgen looks a spec up by the program's head symbol as written: a call
through a record of operations, (ops).op x with ops a concrete
structure instance, is not matched by a spec stated about the field's
body (opImpl x), although the projection of the instance reduces to it.
Expected: vcgen [opImpl_spec] (or vcgen [ops, opImpl_spec]) handles
(ops).op x, the projection reducing to opImpl x.
Observed (v4.35.0 and nightly-2026-10-15): "No spec found for program (ops).op x"
(con-leche: (sharedOpsC mode fe).isDefEq env d a b vs a triple about
opB mode fe d a b).
Workaround: state the callee spec at the projection form (spec_proj).
import Std.WP
import Std.Tactic.Do
open Std.WP
open scoped Lean.Order
set_option experimental.vcgen true
abbrev M := StateT Nat (Except String)
structure Ops where
op : Nat → M Nat
def opImpl (x : Nat) : M Nat := modifyGet fun s => (x, s + 1)
def ops : Ops := ⟨opImpl⟩
def prog (x : Nat) : M Nat := do
let a ← ops.op x
pure (a + 1)
theorem opImpl_spec (x : Nat) {s₀ : Nat} :
⦃fun s => s = s₀⦄ opImpl x ⦃fun v s' => v = x ∧ s' = s₀ + 1; ⊤⦄ := by
sorry
/-- fails: "No spec found for program ops.op x" -/
example (x : Nat) {s₀ : Nat} :
⦃fun s => s = s₀⦄ prog x ⦃fun v _ => v = x + 1; ⊤⦄ := by
sym => vcgen [prog, ops, opImpl_spec] <;> finish
theorem spec_proj (x : Nat) {s₀ : Nat} :
⦃fun s => s = s₀⦄ ops.op x ⦃fun v s' => v = x ∧ s' = s₀ + 1; ⊤⦄ := opImpl_spec x
/-- works -/
example (x : Nat) {s₀ : Nat} :
⦃fun s => s = s₀⦄ prog x ⦃fun v _ => v = x + 1; ⊤⦄ := by
sym => vcgen [prog, spec_proj] <;> finish
- Dominant language
- Lean
- Stars
- 9.6k
- Forks
- 1.1k
- Avg merge
- 1d 17m
- Merged PRs (30d)
- 296
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from leanprover/lean4
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 85/100
leanprover/lean4#15925 ·
Maintainers usually reply within 1 day
-
`IO.appPath` fails when `/proc` belongs to another PID namespacePossibly taken @treiher claimed this 6 days ago. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
leanprover/lean4#15692 · 3 reactions ·
Maintainers usually reply within 1 day
-
`IO.FS.realPath` reports every failure as `noFileOrDirectory` instead of classifying by `errno`Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
leanprover/lean4#15683 ·
Maintainers usually reply within 1 day
-
`Child.pid` leaks the `Child` and its pipe file descriptors (owned argument treated as borrowed)Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
leanprover/lean4#15681 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
leanprover/lean4#15677 ·
Maintainers usually reply within 1 day
All issues in leanprover/lean4
Similar issues
-
area/tools bug session-analysis
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Help-Wanted Needs-Triage Package-Request
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
microsoft/winget-pkgs#461780 ·
Maintainers usually reply within 1 day
-
prompting proposal tool triaged
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
can1357/oh-my-pi#17041 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
cathrynlavery/diagram-design#482 ·
Maintainers usually reply within 2 days
-
automated-analysis bug cookie safe-outputs tool-improvement workflow-issue
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
github/gh-aw#71952 · 3 comments ·
Maintainers usually reply within 1 day