Fix two defects in the solve-limits code found by review - #103
Draft
HowardvanRooijen wants to merge 1 commit into
Draft
HowardvanRooijen wants to merge 1 commit into
HowardvanRooijen wants to merge 1 commit into
Conversation
Both were introduced with the timeout/resource-limit work. The Params object carrying the limits is native-backed and IDisposable, but it was assigned to the solver and dropped without disposing - a native leak on every solve that set a limit. It is now a using, disposed when the check returns, by which point the solver has taken what it needs. A sub-millisecond timeout truncated to zero: (uint)TimeSpan.TotalMillis- econds of 0.5ms is 0, and Z3 reads timeout 0 as no timeout, so a caller asking for a tiny timeout silently got none and would hang on an undecidable theorem. The value now rounds up, so any positive timeout is at least one millisecond. A third review finding - that maximising an unsigned bit-vector might use signed ordering - was measured and does not hold: Z3's MkMaximize on a bit-vector is unsigned, so a uint in [2e9, 3e9] maximises to 2999999999. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PipoHZJsgydrV3JC3fQN6Q
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes two defects a code review of the stack found in the solve-limits work (#96), each verified
by measurement before fixing.
The two defects
A native
Paramsleak.Z3Context.CreateLimitsbuilds aMicrosoft.Z3.Params- which isIDisposable, backed by native memory - andTheorem.Checkassigned it to the solver and droppedit without disposing. Every
Solve/Optimizethat set aTimeoutorResourceLimitleaked one.It is now a
using, disposed whenCheckreturns, by which point the solver has copied what itneeds.
A sub-millisecond timeout silently became no timeout.
(uint)TimeSpan.FromMilliseconds(0.5).TotalMillisecondsis
0, and Z3 readstimeout=0as unlimited - so a caller who asked for a tiny timeout got noneand would hang on an undecidable theorem, exactly the failure the timeout was meant to prevent. The
value now rounds up (
Math.Ceiling), so any positive timeout is at least one millisecond. Measured:Timeout = 0.5mson the sum-of-three-cubes theorem now throwsTheoremUndecidedExceptionin ~1msinstead of running unbounded.
Verified, not a defect
The same review raised, at low confidence, that maximising an unsigned bit-vector might use signed
ordering. Measured and it does not:
MkMaximizeon a bit-vector is unsigned, so auintsymbolconstrained to
[2e9, 3e9]maximises to2999999999and minimises to2000000001- both theunsigned-correct extremes. No change needed; noted here so the finding is closed with evidence.
Not in scope (pre-existing / documented)
double/floatread paths do not strip Z3's trailing?for anon-terminating rational, unlike the
decimalarms. That is onmainunchanged, is open issueCircular decimal last char ‘?’ cannot parse decimal or double #6, and is already pinned by
Solve_{Double,Float}SymbolWithANonTerminatingValue_ThrowsFormatException. Not a regression fromthis stack.
(ulong)uintSymbol,(int)uintSymbol) throwsNotImplementedException. That is the documented limitation from Support uint and ulong as bit-vector symbols #101 -mixing a bit-vector with a conversion is not supported - and it correctly refuses; the raw
exception type is the pre-existing throw-site inconsistency, tracked separately.
Tests
321 -> 322:
Solve_UndecidableTheoremWithASubMillisecondTimeout_StillThrows, guarded by[Timeout]so a return to truncation fails the test rather than hanging. The leak fix is notbehaviourally testable - a leak fails no test - so it is verified by inspection (the
using) andthe green suite; reverting the timeout fix fails the new test, reverting the
usingfails nothing,as expected.
Verification
dotnet build solutions/Z3.Linq.slnx -c Release- clean,TreatWarningsAsErrorsanddocumentation generation on
./build.ps1 -Configuration Release- 46 tasks, 0 errors, 0 warningsRelease note
Releases remain on hold under #60 until Microsoft.Z3 5.x reaches nuget.org, so this reaches
mainbut not consumers. Nothing about the hold changes.
🤖 Generated with Claude Code