Skip to content

Core.formatProgram to produce round-trip-parseable output for all constructs#1165

Merged
MikaelMayer merged 23 commits into
mainfrom
issue-1158-core-formatprogram-does-not-produce-roun
May 18, 2026
Merged

Core.formatProgram to produce round-trip-parseable output for all constructs#1165
MikaelMayer merged 23 commits into
mainfrom
issue-1158-core-formatprogram-does-not-produce-roun

Conversation

@MikaelMayer

@MikaelMayer MikaelMayer commented May 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #1158
Supersedes #1036

Summary

Fixes several issues with Core.formatProgram that prevented round-trip parsing:

  1. inline function formatted without space — The inline grammar op now includes a trailing space, preventing inlinefunction concatenation. The formatter also now emits the inline attribute when present on functions.

  2. Quantifier variable names — The formatter now uses the prettyName field from LExpr.quant instead of generating __qN names, preserving the original variable names through formatting.

  3. Overflow predicates — Added grammar entries, formatter handling, parser entries, and Factory operations for all bitvector overflow predicates (SNegOverflow, UNegOverflow, SAddOverflow, SSubOverflow, SMulOverflow, SDivOverflow, UAddOverflow, USubOverflow, UMulOverflow). SNegOverflow and UNegOverflow use distinct grammar entries (Bv.SNegOverflow / Bv.UNegOverflow) to preserve their different semantics through roundtrip. The translate direction correctly dispatches overflow ops by type parameter (bv1/bv8/bv16/bv32/bv64), logging an error for unsupported widths.

  4. Array assignment (lhsArray) — Implemented m[k] := v translation in both directions: the parser decomposes nested LHS into base identifier + indices and builds map_update expressions; the formatter detects the map_update(var, idx, val) pattern and produces lhsArray syntax.

  5. Sequence.empty — Added grammar entry with explicit type annotation syntax (Sequence.empty<int>()), plus translate and format handling, resolving the 0-ary polymorphic function limitation for this operation. Includes solver verification tests (cherry-picked from feat(core): Add Sequence.empty<T>() syntax for creating empty sequences #1036) covering basic usage and various element types.

  6. Datatype roundtrip — Verified that datatype formatting roundtrips correctly (the extra-parentheses issue noted earlier is resolved).

  7. Roundtrip test infrastructure — Added RoundtripTest.lean that verifies parse → format → re-parse → re-format produces stable output for types, functions, procedures, inline functions, parameterized type arguments, datatypes, array assignments, and Sequence.empty.

  8. getLFuncCall reuse — Refactored lappToExpr and decomposeMapUpdate to use getLFuncCall for decomposing nested applications, reducing code duplication with the existing utility.

Testing

Remaining limitations

  • Bitvector operations with widths beyond 1/8/16/32/64 log an error and fall back to bv64 (requires grammar-level type entries per width)

- Fix inline function formatting: add trailing space to 'inline' op in
  Grammar.lean to prevent 'inlinefunction' concatenation
- Emit inline attribute when formatting functions that have it
- Use prettyName for quantifier variables instead of generated __qN names
- Add overflow predicate support: grammar entries, formatter handling,
  parser entries, and Factory operations for Bv32 overflow predicates
- Add roundtrip test infrastructure for Core programs
- Update test expected outputs to reflect prettyName fix
Resolve conflicts between the formatProgram roundtrip fix and main's
refactoring (FormatCore extraction, recFnDeclToCST, procedure syntax).

- Apply prettyName and inline? fixes to FormatCore.lean
- Use proper overflow CST constructors instead of approximations
- Remove duplicate overflow declarations in Factory.lean
- Update test expected outputs for combined changes
- Fix RoundtripTest to handle new 'program Core;' header
MikaelMayer

This comment was marked as resolved.

… grammar entry

- Overflow ops in translateFn now match on type parameter (.some .bv1,
  .some .bv8, etc.) instead of using wildcard _, consistent with all
  other type-parameterized BV ops.
- Added bv_sdiv_overflow grammar entry so SDivOverflow formats as
  Bv.SDivOverflow(x, y) instead of the incorrect x <= y.
- Added overflow ops to the polymorphic binary dispatch in translateExpr.
- Updated editor syntax files with Bv.SDivOverflow.
@MikaelMayer

This comment was marked as resolved.

@MikaelMayer MikaelMayer changed the title Core.formatProgram does not produce round-trip-parseable output for all constructs Core.formatProgram to produce round-trip-parseable output for all constructs May 14, 2026
… roundtrip

- Implement lhsArray (m[k] := v) in Translate.lean by decomposing nested
  LHS into base identifier + indices and building map_update expressions
- Add decomposeMapUpdate in FormatCore.lean to detect map_update patterns
  and format them back as lhsArray syntax for proper roundtrip
- Add seq_empty grammar entry with explicit type annotation syntax
  (Sequence.empty<T>()) and corresponding translate/format handling
- Add full roundtrip test for datatypes (parentheses issue is resolved)
- Add roundtrip tests for lhsArray and Sequence.empty
- Regenerate editor syntax files with Sequence.empty
- Update AdvancedMaps expected output to match new lhsArray formatting
@MikaelMayer

This comment was marked as resolved.

MikaelMayer

This comment was marked as resolved.

…de, fix docstring

- Add separate bv_uneg_overflow grammar entry so UNegOverflow roundtrips
  correctly (previously both mapped to bv_neg_overflow losing semantics)
- Remove dead bv32NegOverflowFunc/bv32NegOverflowOp definitions
- Fix decomposeMapUpdate docstring to say single-level instead of nested
- Regenerate editor syntax files
Comment thread StrataTest/Languages/Core/Tests/ProgramEvalTests.lean
@MikaelMayer
MikaelMayer marked this pull request as ready for review May 15, 2026 19:04
@MikaelMayer
MikaelMayer requested a review from a team May 15, 2026 19:04
@MikaelMayer
MikaelMayer enabled auto-merge May 15, 2026 20:40
Comment thread Strata/Languages/Core/DDMTransform/ASTtoCST.lean
Comment thread Strata/Languages/Core/DDMTransform/FormatCore.lean Outdated
Comment thread Strata/Languages/Core/DDMTransform/FormatCore.lean Outdated
Comment thread Strata/Languages/Core/Factory.lean Outdated
Comment thread StrataTest/Languages/Core/Examples/AdvancedMaps.lean
shigoel
shigoel previously approved these changes May 15, 2026
joscoh
joscoh previously approved these changes May 15, 2026

@joscoh joscoh left a comment

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.

Nothing blocking but a few minor comments/questions

Comment thread Strata/Languages/Core/DDMTransform/FormatCore.lean Outdated
Comment thread Strata/Languages/Core/DDMTransform/FormatCore.lean Outdated
Comment thread Strata/Languages/Core/DDMTransform/Grammar.lean
@MikaelMayer
MikaelMayer dismissed stale reviews from joscoh and shigoel via af99d91 May 15, 2026 22:23
MikaelMayer and others added 7 commits May 15, 2026 22:32
The getLFuncCall refactoring processes arguments left-to-right, so
variable 'n' is registered as a free variable before the 'top' error
is logged, adding freeVars: [n] to the error context.
Cherry-pick the verification tests (seqEmptyPgm, seqEmptyTypesPgm)
that exercise Sequence.empty with the SMT solver, covering basic usage
and various element types (bool, nested Sequence, Map).
The cherry-pick in 3f3a940 attributed the tests to the wrong author.
Removing them so they can be re-added with correct authorship.
Cherry-pick the verification tests (seqEmptyPgm, seqEmptyTypesPgm)
that exercise Sequence.empty with the SMT solver, covering basic usage
and various element types (bool, nested Sequence, Map).

Co-authored-by: Aaron Tomb <aarotomb@amazon.com>
Comment thread StrataTest/Languages/Core/Examples/Seq.lean Outdated
@MikaelMayer
MikaelMayer added this pull request to the merge queue May 18, 2026
Merged via the queue into main with commit 75e806e May 18, 2026
23 checks passed
@MikaelMayer
MikaelMayer deleted the issue-1158-core-formatprogram-does-not-produce-roun branch May 18, 2026 16:19
PROgram52bc added a commit that referenced this pull request May 21, 2026
Reproduction run on htd/smack tip: regenerated all 12 .bpl via SMACK
Docker, ran run_pipeline.py with all three backends, verified each
known blocker against current source.

- Drop FormatCore.lean blocker (resolved by PR #1165 / 75e806e).
- Refine CBMC structured-body and inout double-collection blockers
  with current source line numbers and observed error messages; the
  visible split is 5 (structured-body) vs 7 (inout) on this run.
- Document the ProcBodyVerifyCorrect.lean type mismatch surfaced and
  fixed during this reproduction (3 call sites swapping proc.body
  for the destructured ss).
- bugFinding partials remain a characterization, not a bug.

Pipeline numbers (deductive 4/7/1, bugFinding 0/11/1, cbmc 0/12) are
unchanged from the previous snapshot, so the results table itself is
left as-is.

Add .gitignore for pipeline-run.log and the local blocker scratch file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Core.formatProgram does not produce round-trip-parseable output for all constructs

4 participants