Skip to content

feat(Core): add Bv{n}.ToUInt, Bv{n}.ToInt, Int.ToBv{n} cast operators#1217

Merged
shigoel merged 6 commits into
strata-org:main2from
kondylidou:pr/casts-core
May 28, 2026
Merged

feat(Core): add Bv{n}.ToUInt, Bv{n}.ToInt, Int.ToBv{n} cast operators#1217
shigoel merged 6 commits into
strata-org:main2from
kondylidou:pr/casts-core

Conversation

@kondylidou
Copy link
Copy Markdown
Contributor

@kondylidou kondylidou commented May 26, 2026

Adds three cross-sort conversion operators to Core, as proposed in #1191.
Split from the original PR per reviewer request — Core layer only.
Boole surface syntax follows in a separate PR.

Operators

Core name SMT-LIB 2.7 Lean Direction
Bv{n}.ToUInt ubv_to_int BitVec.toNat bv → int (unsigned)
Bv{n}.ToInt sbv_to_int BitVec.toInt bv → int (signed, two's complement)
Int.ToBv{n} (_ int_to_bv n) BitVec.ofInt n int → bv (mod 2^n)

Supported widths: 1, 8, 16, 32, 64, 128. All three are total — no
preconditions, no Safe variants, no axioms.

Changes

  • CoreOp: BvOpKind.ToUInt, BvOpKind.ToInt (unary, cross-sort);
    CoreOp.intToBv n
  • Factory: bvToUIntFunc, bvToIntFunc, intToBvFunc + per-width
    instances for all 6 widths; registered in WFFactory
    (factoryOps: 286 → 304)
  • SMTEncoder: maps .bv ⟨_, .ToUInt⟩ubv_to_int,
    .bv ⟨_, .ToInt⟩sbv_to_int, .intToBv n(_ int_to_bv n)
  • DL/SMT/Op: Op.BV.ubv_to_int, Op.BV.sbv_to_int, Op.BV.int_to_bv n
    + mkName entries
  • DL/SMT/Denote + Translate: handle ubv_to_int / sbv_to_int / int_to_bv
  • Core DDMTransform/Grammar + Translate: bv128 type + literal;
    bv128 → .bitvec 128
  • Boole/Verify (minimal): bv128 cases in typeRange,
    toCoreMonoType, bvWidth — required because bv128 enters
    BooleDDM.BooleType via the grammar change above
  • Tests: ProgramEvalTests (18 new func entries for all 3 ops × 6
    widths), StatisticsTest (count bump)

Add three cross-sort conversion operators to Core:
- Bv{n}.ToUInt : Bv{n} → Int  (≙ SMT-LIB ubv_to_int / Lean BitVec.toNat)
- Bv{n}.ToInt  : Bv{n} → Int  (≙ SMT-LIB sbv_to_int / Lean BitVec.toInt)
- Int.ToBv{n}  : Int → Bv{n}  (≙ SMT-LIB int_to_bv / Lean BitVec.ofInt)

Supported widths: 1, 8, 16, 32, 64, 128. All three are total — no
preconditions, no Safe variants, no axioms. SMT-LIB 2.7 operators are
total and agree pointwise with the Lean BitVec definitions.

Changes:
- CoreOp: BvOpKind.ToUInt / .ToInt (unary, cross-sort); CoreOp.intToBv n
- Factory: bvToUIntFunc / bvToIntFunc / intToBvFunc + per-width instances;
  registered in WFFactory (factoryOps count: 286 → 304)
- SMTEncoder: maps .bv ⟨_, .ToUInt⟩ → bv2nat, .bv ⟨_, .ToInt⟩ → sbv2int,
  .intToBv → int_to_bv n
- DL/SMT/Op: Op.BV.bv2nat, Op.BV.sbv2int + mkName entries
- DL/SMT/Denote + Translate: handle bv2nat / sbv2int / int_to_bv
- Core DDMTransform/Grammar: add bv128 type + bv128Lit
- Core DDMTransform/Translate: bv128 → .bitvec 128
- Tests: ProgramEvalTests (18 new func entries), StatisticsTest (count bump)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kondylidou kondylidou requested a review from a team as a code owner May 26, 2026 20:55
@shigoel shigoel added the CSLib PRs and issues marked with this label indicate contributions from/for the CSLib community. label May 26, 2026
Comment thread Strata/DL/SMT/Translate.lean
@shigoel
Copy link
Copy Markdown
Contributor

shigoel commented May 26, 2026

@kondylidou Could we please have some test programs for each new op in Core, all the way down to SMT?

@shigoel
Copy link
Copy Markdown
Contributor

shigoel commented May 27, 2026

@kondylidou Could we please have some test programs for each new op in Core, all the way down to SMT?

Thanks for adding tests, @kondylidou! These tests cover SMT encoding correctness and factory registration. But there's no end-to-end verification test: i.e., a Core program with cast operators that runs through verify and produces pass/fail results from the solver.

Good test candidates would exercise properties like:

  • Provable: Int.ToBv8(Bv8.ToUInt(x)) == x (unsigned roundtrip)
  • Provable: Bv8.ToUInt(bv{8}(255)) == 255
  • Failing: Bv8.ToUInt(x) >= 256 (impossible for 8-bit)
  • Signed semantics: Bv8.ToInt(bv{8}(255)) == -1

@kondylidou
Copy link
Copy Markdown
Contributor Author

@kondylidou Could we please have some test programs for each new op in Core, all the way down to SMT?

Thanks for adding tests, @kondylidou! These tests cover SMT encoding correctness and factory registration. But there's no end-to-end verification test: i.e., a Core program with cast operators that runs through verify and produces pass/fail results from the solver.

Good test candidates would exercise properties like:

  • Provable: Int.ToBv8(Bv8.ToUInt(x)) == x (unsigned roundtrip)
  • Provable: Bv8.ToUInt(bv{8}(255)) == 255
  • Failing: Bv8.ToUInt(x) >= 256 (impossible for 8-bit)
  • Signed semantics: Bv8.ToInt(bv{8}(255)) == -1

Thanks for the feedback! Added BvIntCastVerifyTests.lean with end-to-end verification through cvc5. It covers all four cases you suggested:

  • ProvableInt.ToBv8(Bv8.ToUInt(x)) == x (unsigned roundtrip)
  • ProvableBv8.ToUInt(bv{8}(255)) == 255 (concrete value)
  • ProvableBv8.ToInt(bv{8}(255)) == -1 (signed two's complement semantics)
  • FailingBv8.ToUInt(x) >= 256 (impossible for 8-bit, correctly reported as ❌ fail)

One note on the implementation: factory ops like Bv8.ToUInt can't be called from
#strata program Core; text (the elaborator only resolves names declared in the program
itself, and re-declaring a factory op errors with "already in factory"). So the programs
are constructed via the Lean API using bv8ToUIntFunc.opExpr etc., and verified with
Strata.Core.verifyProgram. The test still exercises the full pipeline —
VCG → SMT encoding → cvc5.

ubv_to_int and sbv_to_int (SMT-LIB 2.7 BV↔Int casts) are not reliably
solved by cvc5 1.2.1; the new cast tests all returned unknown on CI.
I aligned the CI with the version that supports these operators.
@kondylidou
Copy link
Copy Markdown
Contributor Author

ci: bump cvc5 default 1.2.1 → 1.3.4

ubv_to_int and sbv_to_int (SMT-LIB 2.7 BV↔Int casts) are not reliably
solved by cvc5 1.2.1; the new cast tests all returned unknown on CI.
I aligned the CI with the version that supports these operators.

@github-actions github-actions Bot added the github_actions Pull requests that update GitHub Actions code label May 28, 2026
Comment thread StrataTest/Languages/Core/Tests/BvIntCastVerifyTests.lean
@shigoel shigoel added this pull request to the merge queue May 28, 2026
Merged via the queue into strata-org:main2 with commit deab692 May 28, 2026
17 checks passed
@kondylidou kondylidou deleted the pr/casts-core branch May 29, 2026 19:20
PROgram52bc added a commit that referenced this pull request May 29, 2026
Two tests merged from main2 used the pre-#1196 `proc.body : List Statement`
shape. Adapt them to the new `Procedure.Body` sum (`structured` / `cfg`):

- BvIntCastVerifyTests.lean (added by #1217): wrap the literal body list
  with `.structured`.
- Boole/FeatureRequests/seq_empty_literal.lean (added by #1214): pattern-
  match `proc.body` and iterate the `.structured` arm; skip `.cfg` since
  the Boole-to-Core lowering does not produce CFG bodies.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Core CSLib PRs and issues marked with this label indicate contributions from/for the CSLib community. github_actions Pull requests that update GitHub Actions code SMT Waiting-For-Review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants