Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 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
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
43 changes: 40 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,49 @@ 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 total size of the {@link FloatingPointFormula}s {@link
* FloatingPointType}. 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 #toIeeeBitvector(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 with the given {@link BitvectorFormula},
* conforming to the IEEE 754-2008 floating-point format. The size m of the given {@link
* BitvectorFormula} has to be equal to the sum of the sizes of the exponent eb and mantissa sb
* (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 solver dependent. This method is based on a suggestion in the
* (<a href="https://smt-lib.org/theories-FloatingPoint.shtml">SMTLIB2 standard</a>), with eb
* being the {@link FloatingPointFormula}s exponent bit size, sb being its mantissa with the
* hidden bit, and eb + sb equal to the bit size of the used {@link BitvectorFormula} parameter,
* illustrated in SMTLIB2 as:
*
* <p>(= ((_ to_fp eb sb) bitvectorFormulaSetToBeEqualToFpNumber) fpNumber)
*
* <p>Example usage in SMTLIB2, asserting the equality of the 2 parameters:
*
* <p>(declare-fun bitvectorFormulaSetToBeEqualToFpNumber () (_ BitVec m))
*
* <p>(assert (= ((_ to_fp eb sb) bitvectorFormulaSetToBeEqualToFpNumber) fpNumber))
*
* <p>Note: SMTLIB2 output of this method uses the SMTLIB2 keyword 'to_fp' as described above.
*
* @param fpNumber the {@link FloatingPointFormula} to be converted into an IEEE bitvector.
* @param bitvectorFormulaSetToBeEqualToFpNumber 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) bitvectorFormulaSetToBeEqualToFpNumber) fpNumber).
*/
BooleanFormula toIeeeBitvector(
FloatingPointFormula fpNumber, BitvectorFormula bitvectorFormulaSetToBeEqualToFpNumber);

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,82 @@ 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) {
checkArgument(
type.equals(pTypeForAssertions),
"Floating-Point formula %s type %s is not equal to expected type %s",
pTerm,
type,
pTypeForAssertions);
} else {
checkArgument(
type.isFloatingPointType(),
"Floating-Point formula %s has unexpected type: %s",
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 +166,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 @@ -153,14 +197,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 @@ -176,29 +220,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 @@ -237,7 +281,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 @@ -248,7 +294,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 @@ -261,14 +308,14 @@ 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(
() ->
String.format(
"The total size %s of type %s has to match the size %s of type %s.",
pTargetType.getTotalSize(), pTargetType, bvType.getSize(), bvType)));
return wrap(fromIeeeBitvectorImpl(extractInfo(pNumber), pTargetType));
return wrap(fromIeeeBitvectorImpl(extractInfo(pNumber), pTargetType), pTargetType);
}

protected abstract TFormulaInfo fromIeeeBitvectorImpl(
Expand All @@ -279,7 +326,35 @@ 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");
}

@Override
public BooleanFormula toIeeeBitvector(
FloatingPointFormula fpNumber, BitvectorFormula bitvectorFormulaSetToBeEqualToFpNumber) {
FormulaType.FloatingPointType fpType =
(FloatingPointType) getFormulaCreator().getFormulaType(fpNumber);
checkArgument(
fpType.getTotalSize() == bvMgr.getLength(bitvectorFormulaSetToBeEqualToFpNumber),
"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",
bitvectorFormulaSetToBeEqualToFpNumber,
bvMgr.getLength(bitvectorFormulaSetToBeEqualToFpNumber),
fpNumber,
fpType.getTotalSize());

FloatingPointFormula fromIeeeBitvector =
fromIeeeBitvector(bitvectorFormulaSetToBeEqualToFpNumber, 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, fpNumber);
}

@Override
public FloatingPointFormula negate(FloatingPointFormula pNumber) {
Expand Down
62 changes: 46 additions & 16 deletions src/org/sosy_lab/java_smt/basicimpl/AbstractFormulaManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -366,22 +366,27 @@ protected TFormulaInfo parseImpl(String formulaStr) throws IllegalArgumentExcept

@ForOverride
protected List<TFormulaInfo> parseAllImpl(String formulaStr) throws IllegalArgumentException {
// The fallback implementation splits the input into declarations and assertions,
// and parses each assertion separately,
// which is not very efficient, but it works for simple cases and is better than nothing
List<String> tokens = Tokenizer.tokenize(formulaStr);

List<String> declarationTokens =
tokens.stream().filter(Tokenizer::isDeclarationToken).collect(Collectors.toList());
List<String> definitionTokens =
tokens.stream().filter(Tokenizer::isDefinitionToken).collect(Collectors.toList());
List<String> assertTokens =
tokens.stream().filter(Tokenizer::isAssertToken).collect(Collectors.toList());
String definitions =
Joiner.on("").join(declarationTokens) + Joiner.on("").join(definitionTokens);

return Collections3.transformedImmutableListCopy(
assertTokens, assertion -> parseImpl(definitions + assertion));
try {
// The fallback implementation splits the input into declarations and assertions,
// and parses each assertion separately,
// which is not very efficient, but it works for simple cases and is better than nothing
List<String> tokens = Tokenizer.tokenize(formulaStr);

List<String> declarationTokens =
tokens.stream().filter(Tokenizer::isDeclarationToken).collect(Collectors.toList());
List<String> definitionTokens =
tokens.stream().filter(Tokenizer::isDefinitionToken).collect(Collectors.toList());
List<String> assertTokens =
tokens.stream().filter(Tokenizer::isAssertToken).collect(Collectors.toList());
String definitions =
Joiner.on("").join(declarationTokens) + Joiner.on("").join(definitionTokens);

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

} catch (IllegalArgumentException illegalArgumentException) {
throw throwIllegalArgumentExceptionWithBetterErrorMessage(illegalArgumentException);
}
}

/**
Expand Down Expand Up @@ -811,4 +816,29 @@ public final String unescape(String pVar) {
}
return pVar; // unchanged
}

/**
* 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;
}
}
Loading
Loading