Support bitwise ~, <<, >> operators in Python frontend#926
Conversation
Implement Option B from the design document: inline arithmetic identities in the Python Laurel runtime functions. - ~x maps to -(x + 1) - x << n maps to x * int_pow(2, n) - x >> n maps to x / int_pow(2, n) PLShift and PRShift include requires clauses that flag negative shift amounts (which raise ValueError in Python). Changes: - PythonToLaurel.lean: Map Invert->PBitNot, LShift->PLShift, RShift->PRShift - PythonRuntimeLaurelPart.lean: Add PBitNot, PLShift, PRShift functions - PythonRuntimeLaurelPart.lean: Add to AnyMaybeExceptionList - Move test_bitnot, test_lshift, test_rshift from pending/ to tests/ - Add corresponding .expected files Closes #893
|
@keyboardDrummer-bot Add tests for the negative shift case. These tests should catch an error when the right operand is negative. |
Add test_lshift_negative.py and test_rshift_negative.py that verify the requires clauses on PLShift/PRShift correctly flag negative shift amounts as inconclusive.
|
@olivier-aws Added two tests for negative shift amounts in dbc60bf:
Both tests confirm that the Verified locally:
|
…Shift The requires clauses on PLShift/PRShift prevented the verifier from proving AnyMaybeExcept (exception propagation) for these functions. Additionally, PRShift used division (/) which becomes Int.SafeDiv with a non-zero divisor precondition that the verifier couldn't prove for the uninterpreted int_pow function. Changes: - Remove requires clauses from PLShift and PRShift; guard negative shift amounts with inline >= 0 checks instead (matching PPow pattern) - Introduce int_rshift external function to avoid Int.SafeDiv in PRShift - Add intRshiftFunc to PyFactory with concreteEval for constant folding - Update expected test outputs for test_lshift and test_rshift
CI fix pushedThe "Build and test Lean (stable)" check was failing because
Fix
Verification
|
- Rename section from 'other Python operations, currrently unsupported' to 'Python arithmetic and bitwise operations' - Add int_rshift to the external function comment - Update PPow reference to PPow/PRShift
|
Thanks for the review @MikaelMayer! Here's a summary of how I addressed each comment: Nits (fixed in 22924d7):
Soundness questions (answered inline):
I noted in the inline replies that if we want to be conservative about user-defined classes with custom |
joehendrix
left a comment
There was a problem hiding this comment.
I added one clarifying question, but it's more about the expected_laurel directory and how to know when the expected output is correct.
PR asked and pushed by @olivier-aws
Summary
Implements Option B from the design discussion in #893: inline arithmetic identities in the Python Laurel runtime functions to support bitwise
~,<<, and>>operators.Approach
The three operators are modeled using exact arithmetic identities for Python's arbitrary-precision integers:
~x→-(x + 1)(exact for arbitrary-precision integers)x << n→x * int_pow(2, n)(for n ≥ 0)x >> n→x / int_pow(2, n)(for n ≥ 0, using integer division)Negative shift detection
Per @olivier-aws's request,
PLShiftandPRShiftincluderequiresclauses that enforcen >= 0. When the verifier cannot prove the shift amount is non-negative, it flags this as a potential issue — matching Python's runtime behavior of raisingValueErrorfor negative shift counts.Changes
PythonToLaurel.leanInvert→PBitNot,LShift→PLShift,RShift→PRShiftPythonRuntimeLaurelPart.leanPBitNot,PLShift,PRShiftruntime functionsPythonRuntimeLaurelPart.leanAnyMaybeExceptionListtests/pending/→tests/test_bitnot.py,test_lshift.py,test_rshift.pyexpected_laurel/.expectedfiles for the three testsVerification
--check-pendingconfirms 0 pending tests accidentally promoted ✅n >= 0✅Closes #893