Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 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
a7036ef
Merge branch 'master' into 504-ieee-floating-point-to-bitvector-conve…
baierd May 22, 2026
69f86ff
Use assertion instead of precondition for FP type check for more expe…
baierd May 22, 2026
332e001
Make other FP type check before wrapping an assertion as well
baierd May 22, 2026
b2ca7fe
Merge branch 'master' into 504-ieee-floating-point-to-bitvector-conve…
baierd May 22, 2026
3a94b47
Format
baierd May 24, 2026
22473cf
Rename method for FP BV bitwise equality to bitwiseEqual()
baierd May 29, 2026
3d99c92
Make requireNativeFPToBitvector() package-private
baierd Jun 11, 2026
bb10cdb
Remove unused method solverSupportsNativeFPToBitvector()
baierd Jun 11, 2026
ba1ef64
Minimize code in try block of requireNativeFPToBitvector()
baierd Jun 11, 2026
6d32196
Improve grammar in JavaDoc for FloatingPointFormulaManager#bitwiseEqu…
baierd Jun 11, 2026
1997b3a
Improve grammar in JavaDoc for FloatingPointFormulaManager#bitwiseEqu…
baierd Jun 11, 2026
c2601e6
Correct "keyword" to "function symbol in JavaDoc of " FP bitwiseEqual()
baierd Jun 11, 2026
0c8d8f6
Improve parameter names of FP bitwiseEqual()
baierd Jun 11, 2026
2343880
Improve JavaDoc of bitwiseEqual by using an example in our API.
baierd Jun 11, 2026
7114c51
Improve JavaDoc of bitwiseEqual() size requirements
baierd Jun 11, 2026
7d9bbe7
Improve wording in JavaDoc of bitwiseEqual()
baierd Jun 11, 2026
7d0fdaa
Improve JavaDoc of toIeeeBitvector()
baierd Jun 11, 2026
779a4cc
Merge branch 'master' into 504-ieee-floating-point-to-bitvector-conve…
baierd Jun 11, 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
37 changes: 34 additions & 3 deletions src/org/sosy_lab/java_smt/api/FloatingPointFormulaManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -299,12 +299,43 @@ FloatingPointFormula castFrom(
FloatingPointFormula fromIeeeBitvector(BitvectorFormula number, FloatingPointType pTargetType);

/**
* Create a formula that produces a representation of the given floating-point value as a
* bitvector conforming to the IEEE 754-2008 FP format. The bit size of the resulting bitvector is
* equal to the total size of the {@link FloatingPointNumber}s precision.
* Returns a {@link BitvectorFormula} equal to the representation of the given floating-point
* value as a bitvector conforming to the IEEE 754-2008 FP format. The bit size of the resulting
* bitvector is equal to the {@link FloatingPointType#getTotalSize()} of the {@link
* FloatingPointFormula}. This method is not natively supported by all solvers, and SMTLIB2 output
* generated containing formulas originating from this method is often not parsable by other
* solvers. You can use the method {@link #bitwiseEqual(FloatingPointFormula, BitvectorFormula)}
* to avoid both problems.
*/
BitvectorFormula toIeeeBitvector(FloatingPointFormula number);

/**
* Create a {@link BooleanFormula} representing the equality of the bitvector representation of
* the given {@link FloatingPointFormula}s value, conforming to the IEEE 754-2008 floating-point
* format, with the given {@link BitvectorFormula}. The size of the given {@link BitvectorFormula}
* has to be equal to the size returned by {@link FloatingPointType#getTotalSize()} 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 solver dependent. This method is based on a suggestion in the (<a
* href="https://smt-lib.org/theories-FloatingPoint.shtml">SMTLIB2 standard</a>) and is equal to:
*
* <p>assignment(fromIeeeBitvector(bitvectorValue), floatValue)
*
* <p>Note: SMTLIB2 output of this method uses the SMTLIB2 function symbol 'to_fp', for example
* like this: (assert (= ((_ to_fp eb sb) bitvectorValue) floatValue)) with eb being the bit size
* returned by {@link FloatingPointType#getExponentSize()} and sb being the bit size returned by
* {@link FloatingPointType#getMantissaSizeWithHiddenBit()} of the {@link FloatingPointType} of
* floatValue.
*
* @param floatValue the {@link FloatingPointFormula} to be converted into an IEEE bitvector.
* @param bitvectorValue a {@link BitvectorFormula} that is set to be equal to the IEEE bitvector
* representation of the {@link FloatingPointFormula} parameter.
* @return a {@link BooleanFormula} representing the result of the equality of the two parameters,
* i.e. (= ((_ to_fp eb sb) bitvectorValue) floatValue).
*/
BooleanFormula bitwiseEqual(FloatingPointFormula floatValue, BitvectorFormula bitvectorValue);

FloatingPointFormula round(FloatingPointFormula formula, FloatingPointRoundingMode roundingMode);

// ----------------- Arithmetic relations, return type NumeralFormula -----------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@

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.basicimpl.AbstractFormulaManager.checkVariableName;

import com.google.common.base.Preconditions;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
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 +50,14 @@ public abstract class AbstractFloatingPointFormulaManager<TFormulaInfo, TType, T

private final Map<FloatingPointRoundingMode, TFormulaInfo> roundingModes;

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

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

protected abstract TFormulaInfo getDefaultRoundingMode();
Expand All @@ -75,44 +81,76 @@ public FloatingPointRoundingMode fromRoundingModeFormula(
return getFormulaCreator().getRoundingMode(extractInfo(pRoundingModeFormula));
}

protected FloatingPointFormula wrap(TFormulaInfo pTerm) {
/**
* Wraps a native floating-point term in a JavaSMT {@link FloatingPointFormula}. If the {@link
* FloatingPointType} of the term is not available, please use {@link
* AbstractFloatingPointFormulaManager#wrap(Object)}
*
* @param pTypeForAssertions the {@link FloatingPointType} used to create pTerm. This argument is
* only used to verify the exponent and mantissa sizes of pTerm.
*/
protected FloatingPointFormula wrap(
TFormulaInfo pTerm, @Nullable FloatingPointType pTypeForAssertions) {
FormulaType<?> type = getFormulaCreator().getFormulaType(pTerm);
// The type derived from the term in the creator is usually built from the exponent and
// mantissa sizes, hence comparing it to the type used to create the FP term checks that it
// was created correctly. (There are other tests checking FP type correctness)
if (pTypeForAssertions != null) {
assert type.equals(pTypeForAssertions)
: "Floating-Point formula %s with type %s is not equal to expected type %s"
.formatted(pTerm, type, pTypeForAssertions);
} else {
assert type.isFloatingPointType()
: "Floating-Point formula %s has unexpected type: %s".formatted(pTerm, type);
}

return getFormulaCreator().encapsulateFloatingPoint(pTerm);
}

/**
* Wraps a native floating-point term in a JavaSMT {@link FloatingPointFormula}. Please use {@link
* AbstractFloatingPointFormulaManager#wrap(Object, FloatingPointType)} if the {@link
* FloatingPointType} of the term is available.
*/
protected FloatingPointFormula wrap(TFormulaInfo pTerm) {
return wrap(pTerm, null);
}

@Override
public FloatingPointFormula makeNumber(Rational n, FormulaType.FloatingPointType type) {
return wrap(makeNumberImpl(n.toString(), type, getDefaultRoundingMode()));
return wrap(makeNumberImpl(n.toString(), type, getDefaultRoundingMode()), type);
}

@Override
public FloatingPointFormula makeNumber(
Rational n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode) {
return wrap(makeNumberImpl(n.toString(), type, getRoundingMode(pFloatingPointRoundingMode)));
return wrap(
makeNumberImpl(n.toString(), type, getRoundingMode(pFloatingPointRoundingMode)), type);
}

@Override
public FloatingPointFormula makeNumber(double n, FormulaType.FloatingPointType type) {
return wrap(makeNumberImpl(n, type, getDefaultRoundingMode()));
return wrap(makeNumberImpl(n, type, getDefaultRoundingMode()), type);
}

@Override
public FloatingPointFormula makeNumber(
double n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode) {
return wrap(makeNumberImpl(n, type, getRoundingMode(pFloatingPointRoundingMode)));
return wrap(makeNumberImpl(n, type, getRoundingMode(pFloatingPointRoundingMode)), type);
}

protected abstract TFormulaInfo makeNumberImpl(
double n, FormulaType.FloatingPointType type, TFormulaInfo pFloatingPointRoundingMode);

@Override
public FloatingPointFormula makeNumber(BigDecimal n, FormulaType.FloatingPointType type) {
return wrap(makeNumberImpl(n, type, getDefaultRoundingMode()));
return wrap(makeNumberImpl(n, type, getDefaultRoundingMode()), type);
}

@Override
public FloatingPointFormula makeNumber(
BigDecimal n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode) {
return wrap(makeNumberImpl(n, type, getRoundingMode(pFloatingPointRoundingMode)));
return wrap(makeNumberImpl(n, type, getRoundingMode(pFloatingPointRoundingMode)), type);
}

protected TFormulaInfo makeNumberImpl(
Expand All @@ -122,13 +160,13 @@ protected TFormulaInfo makeNumberImpl(

@Override
public FloatingPointFormula makeNumber(String n, FormulaType.FloatingPointType type) {
return wrap(makeNumberImpl(n, type, getDefaultRoundingMode()));
return wrap(makeNumberImpl(n, type, getDefaultRoundingMode()), type);
}

@Override
public FloatingPointFormula makeNumber(
String n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode) {
return wrap(makeNumberImpl(n, type, getRoundingMode(pFloatingPointRoundingMode)));
return wrap(makeNumberImpl(n, type, getRoundingMode(pFloatingPointRoundingMode)), type);
}

/** directly catch the most common special String constants. */
Expand All @@ -148,14 +186,14 @@ protected TFormulaInfo makeNumberImpl(
@Override
public FloatingPointFormula makeNumber(
BigInteger exponent, BigInteger mantissa, Sign sign, FloatingPointType type) {
return wrap(makeNumberImpl(exponent, mantissa, sign, type));
return wrap(makeNumberImpl(exponent, mantissa, sign, type), type);
}

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 All @@ -171,29 +209,29 @@ protected abstract TFormulaInfo makeNumberAndRound(
@Override
public FloatingPointFormula makeVariable(String pVar, FormulaType.FloatingPointType pType) {
checkVariableName(pVar);
return wrap(makeVariableImpl(pVar, pType));
return wrap(makeVariableImpl(pVar, pType), pType);
}

protected abstract TFormulaInfo makeVariableImpl(
String pVar, FormulaType.FloatingPointType pType);

@Override
public FloatingPointFormula makePlusInfinity(FormulaType.FloatingPointType pType) {
return wrap(makePlusInfinityImpl(pType));
return wrap(makePlusInfinityImpl(pType), pType);
}

protected abstract TFormulaInfo makePlusInfinityImpl(FormulaType.FloatingPointType pType);

@Override
public FloatingPointFormula makeMinusInfinity(FormulaType.FloatingPointType pType) {
return wrap(makeMinusInfinityImpl(pType));
return wrap(makeMinusInfinityImpl(pType), pType);
}

protected abstract TFormulaInfo makeMinusInfinityImpl(FormulaType.FloatingPointType pType);

@Override
public FloatingPointFormula makeNaN(FormulaType.FloatingPointType pType) {
return wrap(makeNaNImpl(pType));
return wrap(makeNaNImpl(pType), pType);
}

protected abstract TFormulaInfo makeNaNImpl(FormulaType.FloatingPointType pType);
Expand Down Expand Up @@ -232,7 +270,9 @@ protected abstract TFormulaInfo castToImpl(
@Override
public FloatingPointFormula castFrom(
Formula pNumber, boolean pSigned, FormulaType.FloatingPointType pTargetType) {
return wrap(castFromImpl(extractInfo(pNumber), pSigned, pTargetType, getDefaultRoundingMode()));
return wrap(
castFromImpl(extractInfo(pNumber), pSigned, pTargetType, getDefaultRoundingMode()),
pTargetType);
}

@Override
Expand All @@ -243,7 +283,8 @@ public FloatingPointFormula castFrom(
FloatingPointRoundingMode pFloatingPointRoundingMode) {
return wrap(
castFromImpl(
extractInfo(number), signed, targetType, getRoundingMode(pFloatingPointRoundingMode)));
extractInfo(number), signed, targetType, getRoundingMode(pFloatingPointRoundingMode)),
targetType);
}

protected abstract TFormulaInfo castFromImpl(
Expand All @@ -256,7 +297,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 @@ -273,7 +314,34 @@ 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 "
+ "floating-point formulas to IEEE bitvectors natively");
}
Comment thread
kfriedberger marked this conversation as resolved.

@Override
public BooleanFormula bitwiseEqual(
FloatingPointFormula floatValue, BitvectorFormula bitvectorValue) {
FormulaType.FloatingPointType fpType =
(FloatingPointType) getFormulaCreator().getFormulaType(floatValue);
checkArgument(
fpType.getTotalSize() == bvMgr.getLength(bitvectorValue),
"The size of the bitvector term %s is %s, but needs to be equal to the size of"
+ " the Floating-Point term %s with size %s",
bitvectorValue,
bvMgr.getLength(bitvectorValue),
floatValue,
fpType.getTotalSize());

FloatingPointFormula fromIeeeBitvector = fromIeeeBitvector(bitvectorValue, fpType);

// We use assignment(), as it allows a fp 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.
return assignment(fromIeeeBitvector, floatValue);
}

@Override
public FloatingPointFormula negate(FloatingPointFormula pNumber) {
Expand Down
60 changes: 45 additions & 15 deletions src/org/sosy_lab/java_smt/basicimpl/AbstractFormulaManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -377,23 +377,28 @@ protected List<TFormulaInfo> parseAllImpl(String formulaStr) throws IllegalArgum
ImmutableList.Builder<String> declarationTokens = ImmutableList.builder();
ImmutableList.Builder<String> definitionTokens = ImmutableList.builder();
ImmutableList.Builder<String> assertTokens = ImmutableList.builder();
for (String token : SMTLibTokenizer.of(formulaStr)) {
if (SMTLibTokenizer.isDeclarationToken(token)) {
declarationTokens.add(token);
}
if (SMTLibTokenizer.isDefinitionToken(token)) {
definitionTokens.add(token);
}
if (SMTLibTokenizer.isAssertToken(token)) {
assertTokens.add(token);
try {
for (String token : SMTLibTokenizer.of(formulaStr)) {
if (SMTLibTokenizer.isDeclarationToken(token)) {
declarationTokens.add(token);
}
if (SMTLibTokenizer.isDefinitionToken(token)) {
definitionTokens.add(token);
}
if (SMTLibTokenizer.isAssertToken(token)) {
assertTokens.add(token);
}
}
}
String definitions =
Joiner.on("").join(declarationTokens.build())
+ Joiner.on("").join(definitionTokens.build());
String definitions =
Joiner.on("").join(declarationTokens.build())
+ Joiner.on("").join(definitionTokens.build());

return Collections3.transformedImmutableListCopy(
assertTokens.build(), assertion -> parseImpl(definitions + assertion));

return Collections3.transformedImmutableListCopy(
assertTokens.build(), assertion -> parseImpl(definitions + assertion));
} catch (IllegalArgumentException illegalArgumentException) {
throw throwIllegalArgumentExceptionWithBetterErrorMessage(illegalArgumentException);
}
}

/**
Expand Down Expand Up @@ -1046,4 +1051,29 @@ void applySetLogicCommand() {
}
}
}

/**
* Returns the given {@link IllegalArgumentException} with a potentially improved error message.
* For example: the 'as_ieee_bv' and 'to_ieee_bv' operations are not supported by all SMT solvers,
* as the standard does not define those. We add an explanation to error messages containing those
* operations that explain how to build SMTLIB2 conforming and well accepted SMTLIB2.
*
* @param illegalArgumentException original {@link IllegalArgumentException} wrapping a solvers or
* our initial error message from parsing SMTLIB2.
* @return a {@link IllegalArgumentException} that should be thrown in all cases. Might be the
* original exception.
*/
private IllegalArgumentException throwIllegalArgumentExceptionWithBetterErrorMessage(
IllegalArgumentException illegalArgumentException) throws IllegalArgumentException {
final String msg = illegalArgumentException.getMessage();
if (msg != null && (msg.contains("to_ieee_bv") || msg.contains("as_ieee_bv"))) {
// Better error message for certain cases, explaining common problems
final String additionalMessage =
"; Note: operations 'to_ieee_bv' and 'as_ieee_bv' are not supported in most SMT"
+ " solvers. You can try using the SMTLIB2 standards preferred way to encode this"
+ " operation by utilizing the 'to_fp' operation.";
return new IllegalArgumentException(msg + additionalMessage, illegalArgumentException);
}
return illegalArgumentException;
}
}
4 changes: 0 additions & 4 deletions src/org/sosy_lab/java_smt/basicimpl/FormulaCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,6 @@ protected BitvectorFormula encapsulateBitvector(TFormulaInfo pTerm) {
}

protected FloatingPointFormula encapsulateFloatingPoint(TFormulaInfo pTerm) {
checkArgument(
getFormulaType(pTerm).isFloatingPointType(),
"Floatingpoint formula has unexpected type: %s",
getFormulaType(pTerm));
Comment thread
PhilippWendler marked this conversation as resolved.
return new FloatingPointFormulaImpl<>(pTerm);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,17 @@ public BitvectorFormula toIeeeBitvector(FloatingPointFormula number) {
return result;
}

@Override
public BooleanFormula bitwiseEqual(
FloatingPointFormula floatValue, BitvectorFormula bitvectorValue) {
debugging.assertThreadLocal();
debugging.assertFormulaInContext(floatValue);
debugging.assertFormulaInContext(bitvectorValue);
BooleanFormula res = delegate.bitwiseEqual(floatValue, bitvectorValue);
debugging.addFormulaTerm(res);
return res;
}

@Override
public FloatingPointFormula round(
FloatingPointFormula formula, FloatingPointRoundingMode roundingMode) {
Expand Down
Loading
Loading