Support byte, sbyte and ushort as bounded integer symbols - #102
Draft
HowardvanRooijen wants to merge 1 commit into
Draft
HowardvanRooijen wants to merge 1 commit into
HowardvanRooijen wants to merge 1 commit into
Conversation
The sub-int integer types could not be used as symbols. They cannot be bit-vectors like uint and ulong, because C# promotes them to int in every expression and the promotion would strip a bit-vector sort - so they map to the integer sort instead, bounded to their range, exactly the way short already works. Mapping them to int makes the promotion a no-op in Z3 terms, which is what lets short work and now lets these. They support equality, ordering and arithmetic, and the #87 range bounds keep an out-of-range constraint unsatisfiable rather than read back wrong; they do not support bitwise operators, which need uint or ulong. Every enum underlying type is now a supported type, so a byte-backed enum round-trips like an int-backed one - the pin that expected it to throw becomes a positive test, and the unmapped-cast pin moves from (byte) to (nint), whose TypeCode is Object and which the mapping genuinely has no row for. This is the fix for a byte or ushort member on an environment type a caller cannot rewrite to uint - the case the bit-vector work left with no workaround. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
Makes
byte,sbyteandushortusable as symbols - the case the bit-vector work (#101) leftwith no user-side workaround: a
byteorushortmember on an environment type a caller cannotrewrite to
uint.Why they are integers, not bit-vectors
#101 explained that
byte/ushortcannot be bit-vectors: C# promotes them tointin everyexpression, so
byte & byteis computed inintspace, and a bit-vectorbytesymbol would loseits sort at the
Convert(byte -> int)the compiler inserts. This PR maps them to the integersort instead, which turns that same promotion into a no-op - the symbol is already an integer, so
Convert(byte -> int)passes straight through. That is exactly the mechanism that already makesshortwork;byte,sbyteandushortare its remaining siblings.So they support equality, ordering and arithmetic; they do not support bitwise operators or
shifts, which have no integer counterpart and need
uint/ulong.The change
Additive, ~20 lines of library code:
TryGetSymbolSortgainssbyte/byte/ushortin its integer row.GetBoundsgains their ranges -[0,255],[-128,127],[0,65535]- so A short symbol is not bounded to short's range, so Z3 can pick a value it cannot hold #87 bounds a valuethe type cannot hold to unsatisfiable rather than reading it back wrong.
short.VisitConstantValuefolds them into the integer-constant arm.Measured across every shape: round-trip (incl. each boundary),
Optimizereturning the type'sextreme (
byte-> 255,sbyte-> -128,ushort-> 65535), out-of-range -> unsatisfiable,arithmetic, and array elements.
Enum and cast consequences, handled
Two existing pins changed subject because the supported-type set grew, and both are updated to
match the new truth rather than worked around:
byte/sbyte/short/ushort/int/long-> integer,
uint/ulong-> bit-vector). So abyte-backed enum now round-trips like anint-backed one - measured.Solve_EnumPropertyWithAnUnsupportedUnderlyingType_ThrowsNotSupportedExceptionbecomes
Solve_ByteBackedEnumProperty_RoundTripsTheValue. (Member-constraining is still Enum symbols are not constrained to the members of the enum #97.)(byte)to(nint).byteis now a mapped type, so acast to it resolves;
nint'sTypeCodeisObject, which the mapping genuinely has no rowfor, so it still hits the conversion catch-all.
Tests
305 -> 321. A new
SmallIntegerSymbolTestsfor the three types, plus the two repointed pins aboveand the removal of the byte-not-supported pin from #101.
Solve_{Byte,SByte,UShort}Symbol_RoundTripsTheValueSolve_ByteSymbolsInArithmetic_RoundTripTheValuesOptimize_{Byte,SByte,UShort}Symbol{Max,Min}imised_*Solve_ByteSymbolConstrainedOutsideItsRange_IsUnsatisfiableSolve_ByteBitwise_ThrowsNotSupportedSolve_ByteArrayElement_RoundTripsTheValueSolve_ByteBackedEnumProperty_RoundTripsTheValue(repointed)Mutation results
byte/sbyte/ushortnot mapped to a sortbytebounds rowushortbounds rowsbytebounds rowThe doc guard from #82 also earned its place mid-change: an unbalanced
<para>in the rewordedBitVectorWidthremark was aCS1570build error, caught and fixed before it could ship.Verification
dotnet build solutions/Z3.Linq.slnx -c Release- clean,TreatWarningsAsErrorsanddocumentation generation on
./build.ps1 -Configuration Release- 46 tasks, 0 errors, 0 warningspercentage dips only because the two read switches gained three arms each that the scalar tests
exercise but the element tests reach for one type
Release note
Releases remain on hold under #60 until Microsoft.Z3 5.x reaches nuget.org, so this reaches
mainbut not consumers. The public surface gains
byte/sbyte/ushortsymbol support; nothing isremoved.