-
Notifications
You must be signed in to change notification settings - Fork 57
Add IEEE-754 Floating Point to Bitvector Conversion Fallback #512
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add IEEE-754 Floating Point to Bitvector Conversion Fallback #512
Conversation
…traint is not handed to the user
…gestion + add helper to get mantissa and exponent sizes for FPs (not finished for all solvers)
…n of user defined results for special FP numbers
…ll BV capable solvers
…ings and add it to JavaDoc
…BV transformation and width comparison
…umber mapping) and a test for FP size/mantissa/exponent in relation to BV width for toIeeeBitvector()
…ulaManager (based on solver return)
…d text for native toIeeeBitvector() in AbstractFloatingPointFormulaManager
|
@kfriedberger the SMTLIB2 standard defines the size of an FP as mantissa + exponent with the mantissa including the sign bit. Our current implementation excludes it, and we do not document this properly in all cases, especially the FP type constructor. This is problematic, as the standard defines the size of a BV representation of a FP as My proposal (already WIP):
I don't want to change the current FP-Type constructor, as users expect this to not change behavior. What do you think? I am happy about thoughts/ideas. Edit: it would probably be a good idea to also update the API for |
…tMantissaSizeWithSignBit() +
…he type/mantissa with/without sign bit and add sign bit to toString and toSMTLIBString representations
…a with/without sign bit and use those as far as possible to make the code unambiguous for mantissas
…IEEE BV method availability
…n bit and add some assertions for mantissa/exponent
…guous about the sign bit
…h new mantissa API
…otal size by the types components, and add some documentation
…parsing (because of the new check for "fp.as_ieee_bv" in SMTLIB2 when parsing it and our extended error message)
…rsion-not-supported-in-all-solvers # Conflicts: # src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaFloatingPointManager.java # src/org/sosy_lab/java_smt/solvers/cvc5/CVC5SolverContext.java
…erm and a BV term, returning a boolean formula representing the equality of both according to the IEEE 754-2008 FP format in FP manager
…ters; an FP term and a BV term, returning a boolean formula representing the equality of both according to the IEEE 754-2008 FP format in FP manager
…ith a BitvectorFormula argument and add some more tests for it
…version with a BitvectorFormula argument
|
@kfriedberger @PhilippWendler i now removed the 2 |
…ly in SolverFormulaIOTest
…dOperationException in case of failure
…v" or "as_ieee_bv"
… hand written assumptions
| protected FloatingPointFormula wrapFloatingPointAndAssertType( | ||
| TFormulaInfo pTerm, @Nullable FloatingPointType pTypeForAssertions) { | ||
| checkArgument( | ||
| getFormulaCreator().getFormulaType(pTerm).isFloatingPointType(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The expression getFormulaCreator().getFormulaType(pTerm) is evaluated up to four times on every wrap call. Why not refactor it out into a variable?
Furthermore, checking whether the type is a floating-point type if we check equals() later on anyway is redundant. So I would recommend to execute only one of these checks.
Then the method becomes basically if ... check1 else check2. Now it is useless to delegate from wrapFloatingPoint to wrapFloatingPointAndAssertType. So just put a single check into each of these two methods - much simpler than now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good points! I incorporated them. Thank you!
I originally wanted to switch to using "assert" one we ran all tests and confirmed that we use the API as expected. We might still do that. @kfriedberger whats your opinion on this?
| BitvectorFormulaAndBooleanFormula toIeeeBitvector( | ||
| FloatingPointFormula number, String bitvectorConstantName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just noticed the following: It seems one can use the currently proposed method symmetrically, both for converting from a float to a bitvector and vice versa. After all it creates only an equality between a bv and a float, so I could use it to create an equality between a bitvector constant and a nondet float variable, right?
That would mean that the name toIeeeBitvector is bad because it specifies only one direction and instead the name should indicate the mentioned equality between a float and its bitvector representation. That would also eliminate the awkward bitvectorFormulaSetToBeEqualToFpNumber parameter name.
Then the method should also be referenced in the JavaDoc of the current inverse of toIeeeBitvector.
Btw.: Are there tests for something like I mentioned above?
| * (including the hidden bit) of the given {@link FloatingPointFormula}. This implementation can | ||
| * be used independently of {@link #toIeeeBitvector(FloatingPointFormula)}, as it does not rely on | ||
| * an SMT solvers support for {@link #toIeeeBitvector(FloatingPointFormula)}. Behavior for special | ||
| * FP values (NaN, Inf, etc.) is not defined, and returned values are solver dependent. This |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First, there are no "returned values" here. Second, if behavior is simply mentioned as "not defined" it means that probably almost no caller can safely use it without wrapping it in lots of ITEs, creating a trap in the API. After all, the best way to do something should also be the easiest way.
But I suspect that "not defined" is not really true and one can rely on some behavior rules, just that these are more vague than for other operations, right? What are these rules?
For example, can I rely on the fact that if the float is a NaN that there is at least one bv value that is determined as equal to it? And that no bv value that has a defined float representation could compare as equal to a NaN value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I suspect that "not defined" is not really true and one can rely on some behavior rules, just that these are more vague than for other operations, right? What are these rules?
SMTLIB2 applies. Meaning that, from the point of view of SMTLIB2, there is only one NaN etc. The solvers do accept all valid NaN BV representations when transforming from BV to FP as NaN. But they return just one canonical FP NaN representation per default. I added a test for this.
If a user wants custom behavior for special values, it has to be added by the user uniformly over all FPs. (When i realized that, i removed the version of this method that had the ability to add FP number mappings ;D )
Btw. i checked the default BV representations of NaN in all solvers. Some examples:
MathSAT5: 0 11111111 10000000000000000000000
Z3: 0 11111111 00000000000000000000001
Bitwuzla: 0 11111111 11111111111111111111111
CVC5: 1 11111111 11111111111111111111111
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, can I rely on the fact that if the float is a NaN that there is at least one bv value that is determined as equal to it? And that no bv value that has a defined float representation could compare as equal to a NaN value?
All BV NaN representations seem to work as NaN. When transformed to FP, they are canonized. They do not compare equal as FPs.
Fun fact: no SMT solver returns the same bit representation for NaN as bitvector that is used in the floating-point number when transforming via toIeeeBitvector().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now the JavaDoc just says "Behavior for special FP values (NaN, Inf, etc.), is solver dependent." Wasn't there an explanation about how to handle this at some point, i.e., the hint to handle special values manually by adding conditions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but everyone working with SMT should know how to do this. It might even be dangerous to mention it here; if they don't also modify other sources of BV/FP constants/conversions, unexpected behavior might ensue.
If we knew enough about how these things work or the details, i would be in favor of providing this information. Currently, i don't think that we have the full picture.
…he assertions up to 4 times)
…resentation using fromIeeeBitvector() (BV -> FP)
…rsion-not-supported-in-all-solvers
…and +-Inf as bitvectors
This PR adds a fallback method for
FloatingPointManager.toIeeeBitvector(FloatingPointFormula):FloatingPointManager.toIeeeBitvector(FloatingPointFormula, BitvectorFormula), returns a BooleanFormula that is the result of the equality of the FP input with the BV input (BV is equal to the floating-points bit representation according to the IEEE 754-2008 floating-point format). Special FP numbers are returned as the solver sees fit.Tests for this method have been added. This includes the SMTLIB2 output of it, and the native
toIeeeBitvector()method, showing us what solver can parse what output.Furthermore, i added common FP type checks in the wrapping function of
AbstractFloatingPointFormulaManager