Skip to content

fix(metaverifier): run termCheck and precondElim phases in Core.genVCs - #1471

Open
kondylidou wants to merge 8 commits into
strata-org:mainfrom
kondylidou:fix/gen-vcs-precond-termcheck
Open

kondylidou wants to merge 8 commits into
strata-org:mainfrom
kondylidou:fix/gen-vcs-precond-termcheck

Conversation

@kondylidou

@kondylidou kondylidou commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Problem

Core.genVCs — the reflection path behind the gen_smt_vcs tactic (and
Strata-Boole's gen_smt_vcs_boole) — ran only the loop phases
(insertLoopInvariantAsserts, loopElim) before preSymbolicEvalPipelinePhases.
The full Core.verify pipeline (transformPipelinePhases) additionally runs
termCheckPipelinePhase and precondElimPipelinePhase.

Without precondElimPipelinePhase, any program that declares a function with a
requires clause makes ObligationExtraction.extractObligations fail with

function 'f' still carries a precondition; run precondition elimination
before extracting obligations

genVCs maps that to none, and the tactic reports only "Failed to generate
VCs", so the cause was invisible to users.

Fix

Add termCheckPipelinePhase and precondElimPipelinePhase to the genVCs
phase list, ahead of the loop phases, in the order transformPipelinePhases
uses. Both require only .noCFGBodies, which Boole/Core programs already
satisfy at that point; precondElim establishes .noPrecondsFromFuncs, which
extractObligations expects. Imports for the two modules added.

Besides unblocking such programs, gen_smt_vcs now yields the same
well-formedness (function-precondition) and termination obligations that
Core.verify emits, so the Lean-side certificate covers what the SMT path
checks. Programs with recursive functions or requires-carrying functions will
therefore see additional goals from the tactic.

@kondylidou
kondylidou requested a review from a team September 6, 2026 19:52
kondylidou added a commit to strata-org/Strata-Boole that referenced this pull request Sep 6, 2026
…ate!/take!/drop!

- dalek_sum_of_slice: `scalars : Sequence Scalar` and `Scalar := Sequence int`
  (bytes as ints read with the total `Sequence.select!`; `bytes_are_u8` states
  the [u8; 32] typing facts). No Map, no useArrayTheory. 23 cvc5 obligations,
  strict `all_goals smt` closes every Lean goal. Header documents each
  encoding choice and the differences from the verus-boogie translation.
- Verify.lean: lower Core's total sequence operations (`Sequence.select!`,
  `update!`, `take!`, `drop!`), which the grammar already parsed; regression
  test StrataBooleTest/seq_unsafe_ops.lean, imported from the test root.
- mutual_recursion: with Strata's Core.genVCs now emitting termination and
  well-formedness VCs, the Lean example hits the SMT→Lean bridge's missing
  datatype support (strata-org/Strata#1472); pin the named error via
  #guard_msgs so it flips when the bridge learns datatypes.
- lakefile/manifest: TEMPORARY path dependency on ~/Developer/Strata carrying
  strata-org/Strata#1471 (Core.genVCs runs termCheck + precondElim). Revert to
  git main + `lake update Strata` once #1471 is merged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@kondylidou

Copy link
Copy Markdown
Contributor Author

@shigoel @joscoh this is a very urgent pr can we maybe prioritize it? I need it to be merged until Friday ideally! Thank you so much

@fabiomadge

Copy link
Copy Markdown
Contributor

Can you start by making the CI happy?

@kondylidou

Copy link
Copy Markdown
Contributor Author

Can you start by making the CI happy?

the ci is not failing on one of my changes.

Found 2 files without proper copyright header:
- Strata/Languages/Laurel/Checked/Macros.lean
- Strata/Languages/Laurel/Checked/BuilderM.lean
Error: Process completed with exit code 1.

But I can fix them :)

@kondylidou

Copy link
Copy Markdown
Contributor Author

@fabiomadge can you maybe rerun the ci first, maybe it was already fixed with the new commits

@fabiomadge

Copy link
Copy Markdown
Contributor

Right, this CI probably didn't run on these changes...

@kondylidou

Copy link
Copy Markdown
Contributor Author

@fabiomadge header still missing. should I fix that here?

@fabiomadge

Copy link
Copy Markdown
Contributor

As you wish. I'll get on it, but it'll take a couple of hours until you can rebase.

@kondylidou

Copy link
Copy Markdown
Contributor Author

@fabiomadge fixed

@github-actions github-actions Bot added the Laurel label Sep 8, 2026
kondylidou and others added 2 commits September 9, 2026 11:55
`Core.genVCs` (the reflection path behind `gen_smt_vcs` / `gen_smt_vcs_boole`)
ran only the loop phases before `preSymbolicEvalPipelinePhases`. The full
`Core.verify` pipeline also runs `termCheckPipelinePhase` and
`precondElimPipelinePhase` (transformPipelinePhases). Without the latter, any
program declaring a function with a `requires` clause made
`ObligationExtraction.extractObligations` fail ("function ... still carries a
precondition; run precondition elimination before extracting obligations"),
which `genVCs` turned into `none` and the tactic reported as
"Failed to generate VCs" with no further detail.

Add both phases, in the order the full pipeline uses, ahead of the loop
phases. Besides unblocking such programs, `gen_smt_vcs` now yields the same
well-formedness (function precondition) and termination obligations that
`Core.verify` emits, so the Lean-side certificate covers what the SMT path
checks.

Add a regression test with a `requires`-carrying function used in a
procedure body; before this change the tactic produced no goals for it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ate it

`createGoal` reported only "Error translating query". Since the tactic must
fail rather than drop an obligation it cannot state (dropping would weaken
the bridge axiom's premise), report which VC failed and the bridge error, so
users can tell what the Lean certificate does not cover. Typical trigger:
termination/well-formedness VCs that mention a datatype sort, which the
bridge does not yet declare.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@fabiomadge
fabiomadge force-pushed the fix/gen-vcs-precond-termcheck branch from 285ea85 to 32b24ae Compare September 9, 2026 09:55
@github-actions github-actions Bot removed the Laurel label Sep 9, 2026
`Core.genVCs` (the reflection path behind `gen_smt_vcs`) used to skip that
phase, so `extractObligations` rejected the program ("function ... still
carries a precondition") and the tactic reported "Failed to generate VCs".
This test pins the fix: the goals below include the well-formedness check

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit of a strange comment for a proof of all_goals grind. If we stopped generating the well-formedness check, how would we notice?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it wouldn't have. I checked: if precondElim still runs but stops emitting the call-site assert, all_goals grind passes happily. Switched to closing each obligation by name, which fails with "Case tag set_r_calls_safeDiv_0 not found" in that case, and with "unsolved goals" if an unexpected obligation appears. set_r_calls_safeDiv_0 is the one this PR is actually about, the check that safeDiv's requires holds at its call site in halve.

@kondylidou
kondylidou requested a review from joscoh September 21, 2026 13:01
Review feedback: with `all_goals grind` the test cannot notice a dropped
well-formedness check — it closes whatever goals happen to be there.

Confirmed empirically: making `precondElim` still run but stop emitting the
call-site assert leaves VC generation succeeding with that obligation gone,
and `all_goals grind` still passes. Closing each obligation by name fails in
that case with "Case tag `set_r_calls_safeDiv_0` not found", and with
"unsolved goals" if an unexpected obligation appears, so the test pins the
obligation set in both directions.

`set_r_calls_safeDiv_0` is the obligation this PR is about: the check that
`safeDiv`'s `requires` holds at its call site in `halve`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kondylidou

Copy link
Copy Markdown
Contributor Author

@joscoh @shigoel can we get this in?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants