Skip to content
Open
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
6a91ebf
Remove workaround for toIeeeBitvector() in Bitwuzla as the extra cons…
baierd Aug 13, 2025
5c86496
Add fallback for toIeeeBitvector() based on the SMTLIB2 standards sug…
baierd Aug 13, 2025
06e365f
Add extended toIeeeBitvector() fallback implementation with the optio…
baierd Aug 31, 2025
d00e534
Add bool manager to all FP managers for new toIeeeBitvector() impl
baierd Aug 31, 2025
bc5a5e3
Simplify toIeeeBitvector() fallback implementation
baierd Aug 31, 2025
6e6ec7e
Add CVC4 implementation for getMantissaSize() and getExponentSize()
baierd Aug 31, 2025
f584f6b
Add CVC5 implementation for getMantissaSize() and getExponentSize()
baierd Aug 31, 2025
9df8f21
Add Mathsat5 implementation for getMantissaSize() and getExponentSize()
baierd Aug 31, 2025
105e7f2
Add Z3 implementation for getMantissaSize() and getExponentSize()
baierd Aug 31, 2025
4ec7107
Add internal API to retrieve the width of a BV and implement it for a…
baierd Sep 1, 2025
97c1fe4
Add test for FP special number identity for equal precisions
baierd Sep 1, 2025
fdaabcc
Add preconditions for FP toIeeeBitvector() method special number mapp…
baierd Sep 1, 2025
3ecd133
Add native Mathsat test for mantissa not including the sign bit with …
baierd Sep 1, 2025
52dbeb5
Add tests for FP toIeeeBitvector() fallback (without custom special n…
baierd Sep 1, 2025
353b12c
Add public API to get exponent and mantissa size in FloatingPointForm…
baierd Sep 1, 2025
6c554d0
Add note about mantissa und sign bit in FloatingPointNumber.java
baierd Sep 1, 2025
9603aa6
Remove accidental double implementation of bitvector width getter
baierd Sep 1, 2025
1f09a65
Use existing BV size getter + make size getters for FP public + exten…
baierd Sep 1, 2025
43ee2a0
Extend delegate FloatingPointManagers with FP size methods
baierd Sep 1, 2025
a27cc7e
Rename new FloatingPointFormulaManager method getMantissaSize() to ge…
baierd Sep 1, 2025
de90781
Add JavaDoc to FormulaType.FloatingPointType and add methods to get t…
baierd Sep 1, 2025
b652b7f
Add JavaDoc to FloatingPointNumber and add methods to get the mantiss…
baierd Sep 1, 2025
11926f1
Add suppression of return value to test method checking native FP to …
baierd Sep 1, 2025
17227ac
Extend FP tests with new mantissa API to be unambiguous about the sig…
baierd Sep 1, 2025
31ffd68
Extend FloatingPointFormulaManager with new mantissa API to be unambi…
baierd Sep 1, 2025
3cc3a99
Rename getMantissaSize() in FloatingPointFormulaManager delegates wit…
baierd Sep 1, 2025
cd3a9c1
Update Bitwuzla with new unambiguous FP mantissa size getters
baierd Sep 1, 2025
2fbe5bd
Update CVC4 with new unambiguous FP mantissa size getters
baierd Sep 1, 2025
b789362
Update CVC5 with new unambiguous FP mantissa size getters
baierd Sep 1, 2025
2fc661c
Update MathSAT5 with new unambiguous FP mantissa size getters
baierd Sep 1, 2025
7b2b1de
Update Z3 with new unambiguous FP mantissa size getters
baierd Sep 1, 2025
dbacf94
Update SolverVisitorTest with new unambiguous FP mantissa size getters
baierd Sep 1, 2025
2d27890
Use mantissa size without sign bit when building special numbers to c…
baierd Sep 2, 2025
15efd20
Fix off-by-one FP mantissa bug when casting BV to FP
baierd Sep 2, 2025
ba26c93
Extend FP tests with new tests for toIeeeBitvector() fallback testing…
baierd Sep 2, 2025
9c72a5b
Remove done TODO
baierd Sep 2, 2025
85a5b4e
Rename internal method getMantissaSizeImpl() to getMantissaSizeWithSi…
baierd Sep 2, 2025
edf028d
Apply checkstyle and ECJ suggestions
baierd Sep 2, 2025
567e120
Use type information for FP exponent and mantissa in toIeeeBitvector(…
baierd Sep 2, 2025
87a90df
Extend the exception message for parsing failing due to no support fo…
baierd Nov 2, 2025
6fa0b35
Merge branch 'master' into 504-ieee-floating-point-to-bitvector-conve…
baierd Jan 24, 2026
68aa184
Rename "precision" into type for FP types in AbstractFloatingPointFor…
baierd Jan 29, 2026
de440e1
Use existing FP type inside toIeeeBitvector() method in AbstractFloat…
baierd Jan 29, 2026
8973957
Remove public methods to get the exponent and mantissa of a FP formula
baierd Jan 29, 2026
bfe56ac
Make public methods to get the exponent and mantissa of a FP formula …
baierd Jan 29, 2026
aae26af
Remove (new) methods to retrieve FP mantissa and exponent from Abstra…
baierd Jan 29, 2026
95bd69b
Use fp type total size in toIeeeBitvector() instead of building the t…
baierd Jan 29, 2026
638472c
Add null check before getting a message from a caught exception when …
baierd Jan 29, 2026
faca8c9
Merge branch 'master' into 504-ieee-floating-point-to-bitvector-conve…
baierd Jan 30, 2026
8f3a60e
Add a toIeeeBitvector() implementation based on 2 parameters; an FP t…
baierd Jan 30, 2026
7b2b45b
Improve JavaDoc of toIeeeBitvector() implementation based on 2 parame…
baierd Jan 30, 2026
ddfac9d
Refactor tests for fallback of toIeeeBitvector() to use the version w…
baierd Jan 30, 2026
2fc367e
Remove 2 distinct toIeeeBitvector() fallback methods in favor of the …
baierd Jan 30, 2026
275802e
Re-add accidentally removed JavaDoc of FloatingPointType.getExponentS…
baierd Jan 30, 2026
e5e0c81
Remove problematic implementation of (native) FP toIeeeBitvector() in…
baierd Jan 30, 2026
10df745
Add tests for dumping and parsing SMTLIB2 for the Fp to IEEE BV methods
baierd Jan 30, 2026
9a27db3
Improve error message when parsing SMTLIB2 for the Fp to IEEE BV meth…
baierd Jan 30, 2026
1b6a671
Remove boolean manager from FP manager is it is no longer needed
baierd Jan 30, 2026
24230d9
Remove now unused things from BitwuzlaFloatingPointManager
baierd Jan 30, 2026
76ffa33
Access FloatingPointType.getSinglePrecisionFloatingPointType() direct…
baierd Jan 30, 2026
41c0784
Also remove bool manager from solver implementations of FloatingPoint…
baierd Jan 30, 2026
f805aeb
Improve JavaDoc of solver native toIeeeBitvector() and its Unsupporte…
baierd Jan 30, 2026
a824dac
Improve error msg in case of parsing failure on containing "to_ieee_b…
baierd Jan 30, 2026
2ada968
Switch to requireNativeFPToBitvector() in fpToBvTest instead of using…
baierd Jan 30, 2026
2f98439
Build/get formula type only once when wrapping FP formulas (used in t…
baierd Feb 7, 2026
9e0eee4
Refactor assertions when wrapping FP formulas
baierd Feb 7, 2026
f7ac283
Add 2 new FP tests for NaN representation in BV -> FP and FP -> BV
baierd Feb 7, 2026
1b227a2
Update JavaDoc of FloatingPointFormulaManager toIeeeBitvector() fallback
baierd Feb 7, 2026
9f63898
Fix problem with new FP test and add another new FP tests for NaN rep…
baierd Feb 7, 2026
72ad0e3
Merge branch 'master' into 504-ieee-floating-point-to-bitvector-conve…
baierd Feb 7, 2026
1a5e5dc
Rename NaN bit String variable in FP tests
baierd Feb 7, 2026
86c4ab8
Add a FP test for BV -> FP transformation for special FP numbers +-0 …
baierd Feb 9, 2026
914d367
Fix test in FloatingPointFormulaManagerTest in which solvers return e…
baierd Feb 21, 2026
dba1560
Format
baierd Feb 23, 2026
31d23af
Merge branch 'master' into 504-ieee-floating-point-to-bitvector-conve…
baierd Feb 27, 2026
45e6c92
Merge branch 'master' into 504-ieee-floating-point-to-bitvector-conve…
baierd Mar 26, 2026
e424dfd
Remove Bitwuzla internal tracking for "additional" assertions needed …
baierd Mar 26, 2026
9230799
Remove methods for our internal tracking for "additional" assertions …
baierd Mar 26, 2026
a9a111f
Re-use method return in a variable for parsing errors with better err…
baierd Mar 26, 2026
6b97afc
Correct oversight with double conditions for parsing error handling w…
baierd Mar 26, 2026
37d5fce
Move re-throwing of IllegalArgumentException for improved parsing err…
baierd Mar 26, 2026
955c029
Simplify wrapping of FP terms in AbstractFloatingPointFormulaManager
baierd Mar 27, 2026
ddc38ce
Simplify wrapping of FP terms in AbstractFloatingPointFormulaManager …
baierd Mar 27, 2026
2405704
Add new method for cases in which checks that dump is parseable is ex…
baierd Mar 27, 2026
a669c12
Merge branch 'master' into 504-ieee-floating-point-to-bitvector-conve…
baierd Apr 28, 2026
5501179
Update switch case to J17 for BV to FP special value single prec FP test
baierd Apr 30, 2026
81a928c
Revert changes to IntelliJ misc
baierd Apr 30, 2026
4ffac52
Extend test for generic FP special number from BV and their model values
baierd May 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions src/org/sosy_lab/java_smt/api/FloatingPointFormulaManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;
import org.sosy_lab.common.rationals.Rational;
import org.sosy_lab.java_smt.api.FloatingPointNumber.Sign;
import org.sosy_lab.java_smt.api.FormulaType.FloatingPointType;
import org.sosy_lab.java_smt.basicimpl.AbstractFloatingPointFormulaManager.BitvectorFormulaAndBooleanFormula;
Comment thread
PhilippWendler marked this conversation as resolved.
Outdated

/**
* Floating point operations.
Expand Down Expand Up @@ -305,6 +307,71 @@ FloatingPointFormula castFrom(
*/
BitvectorFormula toIeeeBitvector(FloatingPointFormula number);

/**
* Create a formula that produces a representation of the given floating-point value as a
* bitvector conforming to the IEEE 754-2008 format. The size of the resulting bitvector is the
* sum of the sizes of the exponent and mantissa of the input formula plus 1 (for the sign bit).
* 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. In case you want to define how to
* handle those values, please use {@link #toIeeeBitvector(FloatingPointFormula, String, Map)}.
* This method is based on a suggestion in the SMTLib2 standard (<a
* href="https://smt-lib.org/theories-FloatingPoint.shtml">source</a>) implementation:
*
* <p>(declare-fun b () (_ BitVec m))
*
* <p>(assert (= ((_ to_fp eb sb) b) f))
*
* <p>Note: SMTLIB2 output of this method uses the SMTLIB2 keyword 'to_fp' as described above and
* no keyword variation for floating-point to bitvector conversion like 'fp.as_ieee_bv'.
*
* @param number the {@link FloatingPointFormula} to be converted into an IEEE bitvector.
* @param bitvectorConstantName the name of the returned {@link BitvectorFormula}.
Comment thread
PhilippWendler marked this conversation as resolved.
Outdated
* @return {@link BitvectorFormulaAndBooleanFormula} consisting of the transformed input
* floating-point as a {@link BitvectorFormula} and the additional constraint as {@link
* BooleanFormula}.
*/
BitvectorFormulaAndBooleanFormula toIeeeBitvector(
FloatingPointFormula number, String bitvectorConstantName);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overloading methods can be confusing and error prone, and should be used only in cases where the semantics are clear and it is obvious what the differences are from the differing parameters.

But here this is clearly not the case. We have an operation (converting from float to bv) that has the obvious signature FloatingPointFormula -> BitvectorFormula. Nobody will understand why this operation should also take a String, and what the difference is between the same operation with and without the String.

So I recommend to reconsider the choice for an overload here and suggest renaming the new methods such that their names explain what they do.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason i named it like this is that this is how the SMTLIB2 standard actually recommends this operation to be implemented. It performs the same operation as BitvectorFormula toIeeeBitvector(FloatingPointFormula pNumber), just with an extra input.

The main advantage is that users familiar with toIeeeBitvector() find the new call(s) immediately, and it is clear what they do (i.e. they actually perform the same operation).

Note: i now removed the 2 toIeeeBitvector() fallback methods you reviewed in favor of a single new one.

Copy link
Copy Markdown
Member

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?


/**
* Create a formula that produces a representation of the given floating-point value as a
* bitvector conforming to the IEEE 754-2008 format. The size of the resulting bitvector is the
* sum of the sizes of the exponent and mantissa of the input formula plus 1 (for the sign bit).
* 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.)
* can be defined using the specialFPConstantHandling parameter. This method is based on a
* suggestion in the SMTLib2 standard (<a
* href="https://smt-lib.org/theories-FloatingPoint.shtml">source</a>) implementation:
*
* <p>(declare-fun b () (_ BitVec m))
*
* <p>(assert (= ((_ to_fp eb sb) b) f))
*
* <p>Note: SMTLIB2 output of this method uses the SMTLIB2 keyword 'to_fp' as described above and
* no keyword variation for floating-point to bitvector conversion like 'fp.as_ieee_bv'.
*
* @param number the {@link FloatingPointFormula} to be converted into an IEEE bitvector.
* @param bitvectorConstantName the name of the returned {@link BitvectorFormula}.
* @param specialFPConstantHandling a {@link Map} defining the returned {@link BitvectorFormula}
* for special {@link FloatingPointFormula} constant numbers. You are only allowed to specify
* a mapping for special FP numbers with more than one well-defined bitvector representation,
* i.e. NaN and +/- Infinity. The width of the mapped bitvector values has to match the
Comment thread
PhilippWendler marked this conversation as resolved.
Outdated
* expected width of the bitvector return value. The {@link FloatingPointType}, i.e.
* precision, of the key FP numbers has to match the {@link FloatingPointType} of the
* parameter {@code number}. For an empty {@link Map}, or missing mappings, this method
* behaves like {@link #toIeeeBitvector(FloatingPointFormula, String)}.
* @return {@link BitvectorFormulaAndBooleanFormula} consisting of the transformed input
* floating-point as a {@link BitvectorFormula} and the additional constraint as {@link
* BooleanFormula}.
*/
BitvectorFormulaAndBooleanFormula toIeeeBitvector(
FloatingPointFormula number,
String bitvectorConstantName,
Map<FloatingPointFormula, BitvectorFormula> specialFPConstantHandling);

FloatingPointFormula round(FloatingPointFormula formula, FloatingPointRoundingMode roundingMode);

// ----------------- Arithmetic relations, return type NumeralFormula -----------------
Expand Down Expand Up @@ -482,4 +549,13 @@ FloatingPointFormula multiply(
* </ul>
*/
BooleanFormula isNegative(FloatingPointFormula number);

/**
* Returns the size of the mantissa (also called a coefficient or significant), including the sign
* bit, for the given {@link FloatingPointFormula}.
*/
int getMantissaSizeWithSignBit(FloatingPointFormula number);

/** Returns the size of the exponent for the given {@link FloatingPointFormula}. */
int getExponentSize(FloatingPointFormula number);
Comment thread
kfriedberger marked this conversation as resolved.
Outdated
}
1 change: 0 additions & 1 deletion src/org/sosy_lab/java_smt/api/FormulaType.java
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,6 @@ public boolean isFloatingPointType() {
return true;
}

/** Returns the size of the exponent. */
Comment thread
PhilippWendler marked this conversation as resolved.
public int getExponentSize() {
return exponentSize;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@

package org.sosy_lab.java_smt.basicimpl;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.sosy_lab.java_smt.api.FormulaType.getFloatingPointTypeFromSizesWithoutHiddenBit;
import static org.sosy_lab.java_smt.basicimpl.AbstractFormulaManager.checkVariableName;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.sosy_lab.common.MoreStrings;
import org.sosy_lab.common.rationals.Rational;
import org.sosy_lab.java_smt.api.BitvectorFormula;
Expand Down Expand Up @@ -48,10 +54,18 @@ public abstract class AbstractFloatingPointFormulaManager<TFormulaInfo, TType, T

private final Map<FloatingPointRoundingMode, TFormulaInfo> roundingModes;

private final AbstractBitvectorFormulaManager<TFormulaInfo, TType, TEnv, TFuncDecl> bvMgr;

private final AbstractBooleanFormulaManager<TFormulaInfo, TType, TEnv, TFuncDecl> bMgr;

protected AbstractFloatingPointFormulaManager(
FormulaCreator<TFormulaInfo, TType, TEnv, TFuncDecl> pCreator) {
FormulaCreator<TFormulaInfo, TType, TEnv, TFuncDecl> pCreator,
AbstractBitvectorFormulaManager<TFormulaInfo, TType, TEnv, TFuncDecl> pBvMgr,
AbstractBooleanFormulaManager<TFormulaInfo, TType, TEnv, TFuncDecl> pBMgr) {
super(pCreator);
roundingModes = new HashMap<>();
bvMgr = pBvMgr;
bMgr = pBMgr;
}

protected abstract TFormulaInfo getDefaultRoundingMode();
Expand Down Expand Up @@ -160,7 +174,7 @@ protected abstract TFormulaInfo makeNumberImpl(
BigInteger exponent, BigInteger mantissa, Sign sign, FloatingPointType type);

protected static boolean isNegativeZero(Double pN) {
Preconditions.checkNotNull(pN);
checkNotNull(pN);
return Double.valueOf("-0.0").equals(pN);
}

Expand Down Expand Up @@ -261,7 +275,7 @@ protected abstract TFormulaInfo castFromImpl(
public FloatingPointFormula fromIeeeBitvector(
BitvectorFormula pNumber, FloatingPointType pTargetType) {
BitvectorType bvType = (BitvectorType) formulaCreator.getFormulaType(pNumber);
Preconditions.checkArgument(
checkArgument(
bvType.getSize() == pTargetType.getTotalSize(),
MoreStrings.lazyString(
() ->
Expand All @@ -279,7 +293,99 @@ public BitvectorFormula toIeeeBitvector(FloatingPointFormula pNumber) {
return getFormulaCreator().encapsulateBitvector(toIeeeBitvectorImpl(extractInfo(pNumber)));
}

protected abstract TFormulaInfo toIeeeBitvectorImpl(TFormulaInfo pNumber);
@SuppressWarnings("unused")
protected TFormulaInfo toIeeeBitvectorImpl(TFormulaInfo pNumber) {
throw new UnsupportedOperationException(
"The chosen solver does not support transforming "
+ "FloatingPointFormula to IEEE bitvectors. Try using the fallback "
+ "methods toIeeeBitvector"
+ "(FloatingPointFormula, String) and/or "
+ "toIeeeBitvector(FloatingPointFormula, String, Map)");
}
Comment thread
kfriedberger marked this conversation as resolved.

@Override
public BitvectorFormulaAndBooleanFormula toIeeeBitvector(
FloatingPointFormula f, String bitvectorConstantName) {
return toIeeeBitvector(f, bitvectorConstantName, ImmutableMap.of());
}

@Override
public BitvectorFormulaAndBooleanFormula toIeeeBitvector(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is weird. Does is really handle NaN as expected?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SMTLIB2 does not define a default NaN beyond its representation in SMTLIB2. But it warns that there are multiple possible binary representations. It states that:

 :note
 "There is no function for converting from (_ FloatingPoint eb sb) to the
  corresponding IEEE 754-2008 binary format, as a bit vector (_ BitVec m) with 
  m = eb + sb, because (_ NaN eb sb) has multiple, well-defined representations.
  Instead, an encoding of the kind below is recommended, where f is a term
  of sort (_ FloatingPoint eb sb):

   (declare-fun b () (_ BitVec m))
   (assert (= ((_ to_fp eb sb) b) f))
 "

Hence i thought it might be beneficial to have 2 methods; one that handles NaN simply the way the solver handles it, the other in such a way that you can configure it (and other special values, as infinity suffers from a similar problem as NaN). If a user decides to use a distinct encoding of NaN that is not used by the solver per default, it is possible with this method.

However, we can easily make the argument that every user can wrap the public BitvectorFormulaAndBooleanFormula toIeeeBitvector(FloatingPointFormula f, String bitvectorConstantName) method in ITE formulas themselves.

Do you think we should just remove the marked method and add some info in the JavaDoc?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: i replaced the 2 methods with a single one taking only a FP and a BV formula. The behavior is the same as in this method.

FloatingPointFormula f,
String bitvectorConstantName,
Map<FloatingPointFormula, BitvectorFormula> specialFPConstantHandling) {

FormulaType.FloatingPointType fpType =
(FloatingPointType) getFormulaCreator().getFormulaType(f);
// The BV is sign bit + exponent + mantissa without hidden bit
int mantissaSizeWithoutHiddenBit = fpType.getMantissaSizeWithoutHiddenBit();
int exponentSize = fpType.getExponentSize();
BitvectorFormula bvFormula =
bvMgr.makeVariable(1 + exponentSize + mantissaSizeWithoutHiddenBit, bitvectorConstantName);
Comment thread
PhilippWendler marked this conversation as resolved.
Outdated

// When building new Fp types, we don't include the sign bit
FloatingPointFormula fromIeeeBitvector =
fromIeeeBitvector(
bvFormula,
getFloatingPointTypeFromSizesWithoutHiddenBit(
exponentSize, mantissaSizeWithoutHiddenBit));
Comment thread
PhilippWendler marked this conversation as resolved.
Outdated

// assignment() allows a value to be NaN etc.
// Note: All fp.to_* functions are unspecified for NaN and infinity input values in the
// standard, what solvers return might be distinct.
BooleanFormula additionalConstraint = assignment(fromIeeeBitvector, f);

// Build special numbers so that we can compare them in the map
FloatingPointType precision =
getFloatingPointTypeFromSizesWithoutHiddenBit(exponentSize, mantissaSizeWithoutHiddenBit);
Comment thread
PhilippWendler marked this conversation as resolved.
Outdated
Set<FloatingPointFormula> specialNumbers =
ImmutableSet.of(
makeNaN(precision), makePlusInfinity(precision), makeMinusInfinity(precision));

BitvectorFormula toIeeeBv = bvFormula;
for (Entry<FloatingPointFormula, BitvectorFormula> entry :
specialFPConstantHandling.entrySet()) {
FloatingPointFormula fpConst = entry.getKey();

// We check that FP const special numbers are used (info from SMTLib2-standard)
// NaN has multiple possible definitions.
// +/- Infinity each has 2; e.g., +infinity for sort (_ FloatingPoint 2 3) is represented
// equivalently by (_ +oo 2 3) and (fp #b0 #b11 #b00).
// -0 only has one representation; i.e. (_ -zero 3 2) abbreviates (fp #b1 #b000 #b0), and
// is therefore disallowed.
// This automatically checks the correct precision as well!
checkArgument(
specialNumbers.contains(fpConst),
"You are only allowed to specify a mapping for special FP numbers with more than one"
+ " well-defined bitvector representation, i.e. NaN and +/- Infinity. Their precision"
+ " has to match the precision of the formula to be represented as bitvector.");

BitvectorFormula bvTerm = entry.getValue();
checkArgument(
bvMgr.getLength(bvTerm) == bvMgr.getLength(bvFormula),
"The size of the bitvector terms used as mapped values needs to be equal to the size of"
+ " the bitvector returned by this method");

BooleanFormula assumption = assignment(fpConst, f);
toIeeeBv = bMgr.ifThenElse(assumption, bvTerm, toIeeeBv);
}

return BitvectorFormulaAndBooleanFormula.of(toIeeeBv, additionalConstraint);
}

@Override
public int getMantissaSizeWithSignBit(FloatingPointFormula f) {
return getMantissaSizeWithSignBitImpl(extractInfo(f));
}

protected abstract int getMantissaSizeWithSignBitImpl(TFormulaInfo f);

@Override
public int getExponentSize(FloatingPointFormula f) {
return getExponentSizeImpl(extractInfo(f));
}

protected abstract int getExponentSizeImpl(TFormulaInfo f);

@Override
public FloatingPointFormula negate(FloatingPointFormula pNumber) {
Expand Down Expand Up @@ -542,4 +648,28 @@ protected static String getBvRepresentation(BigInteger integer, int size) {
}
return String.copyValueOf(values);
}

public static final class BitvectorFormulaAndBooleanFormula {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use a Google-Auto-class? In the future this might be a record.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clearly a record once we update.

I didn't think about auto-classes while writing. But i would prefer to switch to records once we update. (Which is 100% personal preference. I don't mind if we go with auto-classes.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to make this a record in the future, you should already now design the (non-private parts of the) API such that making it a record will be compatible.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class has been removed.

private final BitvectorFormula bitvectorFormula;
private final BooleanFormula booleanFormula;

private BitvectorFormulaAndBooleanFormula(
BitvectorFormula pBitvectorFormula, BooleanFormula pBooleanFormula) {
bitvectorFormula = checkNotNull(pBitvectorFormula);
booleanFormula = checkNotNull(pBooleanFormula);
}

private static BitvectorFormulaAndBooleanFormula of(
Comment thread
PhilippWendler marked this conversation as resolved.
Outdated
BitvectorFormula pBitvectorFormula, BooleanFormula pBooleanFormula) {
return new BitvectorFormulaAndBooleanFormula(pBitvectorFormula, pBooleanFormula);
}

public BitvectorFormula getBitvectorFormula() {
return bitvectorFormula;
}

public BooleanFormula getBooleanFormula() {
return booleanFormula;
}
}
}
18 changes: 17 additions & 1 deletion src/org/sosy_lab/java_smt/basicimpl/AbstractFormulaManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,23 @@ private String sanitize(String formulaStr) {

@Override
public BooleanFormula parse(String formulaStr) throws IllegalArgumentException {
return formulaCreator.encapsulateBoolean(parseImpl(sanitize(formulaStr)));
try {
return formulaCreator.encapsulateBoolean(parseImpl(sanitize(formulaStr)));
} catch (IllegalArgumentException illegalArgumentException) {
if (illegalArgumentException.getMessage().contains("fp.as_ieee_bv")) {
String additionalMessage =
"; Note: operation 'fp.as_ieee_bv' is not supported in most SMT solvers. Instead, try"
+ " utilizing the SMTLIB2 keyword 'to_fp' which is supported in most SMT solvers"
+ " with Bitvector and Floating-Point support. In case the SMTLIB2 output has been"
+ " created using JavaSMT, try replacing the FloatingPointFormulaManager method"
+ " toIeeeBitvector(FloatingPointFormula), with either"
+ " toIeeeBitvector(FloatingPointFormula, String) or"
+ " toIeeeBitvector(FloatingPointFormula, String, Map).";
throw new IllegalArgumentException(
illegalArgumentException.getMessage() + additionalMessage, illegalArgumentException);
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4x getMessage --> maybe use a variable for that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Thanks for noticing!

I also extracted it into a method and moved the call due to how parsing was changed in parseAll().

throw illegalArgumentException;
}
}

protected abstract String dumpFormulaImpl(TFormulaInfo t) throws IOException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;
import org.sosy_lab.common.rationals.Rational;
import org.sosy_lab.java_smt.api.BitvectorFormula;
import org.sosy_lab.java_smt.api.BooleanFormula;
Expand All @@ -21,6 +22,7 @@
import org.sosy_lab.java_smt.api.Formula;
import org.sosy_lab.java_smt.api.FormulaType;
import org.sosy_lab.java_smt.api.FormulaType.FloatingPointType;
import org.sosy_lab.java_smt.basicimpl.AbstractFloatingPointFormulaManager.BitvectorFormulaAndBooleanFormula;

public class DebuggingFloatingPointFormulaManager implements FloatingPointFormulaManager {
private final FloatingPointFormulaManager delegate;
Expand Down Expand Up @@ -224,6 +226,36 @@ public BitvectorFormula toIeeeBitvector(FloatingPointFormula number) {
return result;
}

@Override
public BitvectorFormulaAndBooleanFormula toIeeeBitvector(
FloatingPointFormula number, String bitvectorConstantName) {
debugging.assertThreadLocal();
debugging.assertFormulaInContext(number);
BitvectorFormulaAndBooleanFormula res = delegate.toIeeeBitvector(number, bitvectorConstantName);
debugging.addFormulaTerm(res.getBitvectorFormula());
debugging.addFormulaTerm(res.getBooleanFormula());
return res;
}

@Override
public BitvectorFormulaAndBooleanFormula toIeeeBitvector(
FloatingPointFormula number,
String bitvectorConstantName,
Map<FloatingPointFormula, BitvectorFormula> specialFPConstantHandling) {
debugging.assertThreadLocal();
debugging.assertFormulaInContext(number);
specialFPConstantHandling.forEach(
(key, value) -> {
debugging.assertFormulaInContext(key);
debugging.assertFormulaInContext(value);
});
BitvectorFormulaAndBooleanFormula res =
delegate.toIeeeBitvector(number, bitvectorConstantName, specialFPConstantHandling);
debugging.addFormulaTerm(res.getBitvectorFormula());
debugging.addFormulaTerm(res.getBooleanFormula());
return res;
}

@Override
public FloatingPointFormula round(
FloatingPointFormula formula, FloatingPointRoundingMode roundingMode) {
Expand Down Expand Up @@ -509,4 +541,18 @@ public BooleanFormula isNegative(FloatingPointFormula number) {
debugging.addFormulaTerm(result);
return result;
}

@Override
public int getMantissaSizeWithSignBit(FloatingPointFormula number) {
debugging.assertThreadLocal();
debugging.assertFormulaInContext(number);
return delegate.getMantissaSizeWithSignBit(number);
}

@Override
public int getExponentSize(FloatingPointFormula number) {
debugging.assertThreadLocal();
debugging.assertFormulaInContext(number);
return delegate.getExponentSize(number);
}
}
Loading