Skip to content

Commit c6d2ca7

Browse files
authored
Merge pull request #508 from sosy-lab/roundingMode
Allow users to build new rounding mode formulas
2 parents 5a605ba + 2fb2643 commit c6d2ca7

17 files changed

+387
-57
lines changed

src/org/sosy_lab/java_smt/api/FloatingPointFormulaManager.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
// an API wrapper for a collection of SMT solvers:
33
// https://github.com/sosy-lab/java-smt
44
//
5-
// SPDX-FileCopyrightText: 2020 Dirk Beyer <https://www.sosy-lab.org>
5+
// SPDX-FileCopyrightText: 2025 Dirk Beyer <https://www.sosy-lab.org>
66
//
77
// SPDX-License-Identifier: Apache-2.0
88

99
package org.sosy_lab.java_smt.api;
1010

11+
import static org.sosy_lab.java_smt.api.FormulaManager.API_METHOD_NOT_IMPLEMENTED;
1112
import static org.sosy_lab.java_smt.api.FormulaType.getFloatingPointType;
1213

1314
import java.math.BigDecimal;
@@ -34,6 +35,19 @@
3435
*/
3536
public interface FloatingPointFormulaManager {
3637

38+
/** Creates a formula for the given floating point rounding mode. */
39+
FloatingPointRoundingModeFormula makeRoundingMode(FloatingPointRoundingMode pRoundingMode);
40+
41+
/**
42+
* Converts a rounding mode formula to the corresponding enum value. This method is the inverse of
43+
* {@link #makeRoundingMode(FloatingPointRoundingMode)}.
44+
*/
45+
@SuppressWarnings("unused")
46+
default FloatingPointRoundingMode fromRoundingModeFormula(
47+
FloatingPointRoundingModeFormula pRoundingModeFormula) {
48+
throw new UnsupportedOperationException(API_METHOD_NOT_IMPLEMENTED);
49+
}
50+
3751
/**
3852
* Creates a floating point formula representing the given double value with the specified type.
3953
*/

src/org/sosy_lab/java_smt/api/FloatingPointRoundingMode.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22
// an API wrapper for a collection of SMT solvers:
33
// https://github.com/sosy-lab/java-smt
44
//
5-
// SPDX-FileCopyrightText: 2020 Dirk Beyer <https://www.sosy-lab.org>
5+
// SPDX-FileCopyrightText: 2025 Dirk Beyer <https://www.sosy-lab.org>
66
//
77
// SPDX-License-Identifier: Apache-2.0
88

99
package org.sosy_lab.java_smt.api;
1010

11-
/** Possible floating point rounding modes. */
11+
/**
12+
* Represents the various rounding modes that can be applied when converting or manipulating
13+
* floating-point values and formulas. These modes define how results are rounded when an exact
14+
* representation is not possible due to precision limits of the target format.
15+
*/
1216
public enum FloatingPointRoundingMode {
1317
NEAREST_TIES_TO_EVEN,
1418
NEAREST_TIES_AWAY,

src/org/sosy_lab/java_smt/api/FloatingPointRoundingModeFormula.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,15 @@
1111
import com.google.errorprone.annotations.Immutable;
1212

1313
/**
14-
* Formula representing a rounding mode for floating-point operations. This is currently unused by
15-
* the API but necessary for traversal of formulas with such terms.
14+
* Formula representing a rounding mode for floating-point operations.
15+
*
16+
* <p>Rounding mode formulas are used by floating-point formulas to select the rounding mode for the
17+
* operation. Use {@link FloatingPointFormulaManager#makeRoundingMode(FloatingPointRoundingMode)} to
18+
* wrap a {@link org.sosy_lab.java_smt.api.FloatingPointRoundingMode} value inside a new formula.
19+
*
20+
* <p>This class is rarely used in the API but necessary to support visitor traversal of formulas
21+
* with certain floating-point operations, where JavaSMT provides the rounding mode as Formula-based
22+
* argument.
1623
*/
1724
@Immutable
1825
public interface FloatingPointRoundingModeFormula extends Formula {}

src/org/sosy_lab/java_smt/api/FormulaManager.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@
2020
/** FormulaManager class contains all operations which can be performed on formulas. */
2121
public interface FormulaManager {
2222

23+
/**
24+
* Standardized message for not implemented API methods.
25+
*
26+
* <p>This constant can be used in {@link UnsupportedOperationException} to indicate that a
27+
* certain method is not implemented by some subclass. We recommend using this constant in API
28+
* extensions where the default implementation throws an exception.
29+
*/
30+
String API_METHOD_NOT_IMPLEMENTED =
31+
"The requested method is not implemented in the current implementation of this interface.";
32+
2333
/**
2434
* Returns the Integer-Theory. Because most SAT-solvers support automatic casting between Integer-
2535
* and Rational-Theory, the Integer- and the RationalFormulaManager both return the same Formulas

src/org/sosy_lab/java_smt/api/FunctionDeclarationKind.java

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -261,21 +261,6 @@ public enum FunctionDeclarationKind {
261261
/** Equal over floating points. */
262262
FP_EQ,
263263

264-
/** Rounding over floating points. */
265-
FP_ROUND_EVEN,
266-
267-
/** Rounding over floating points. */
268-
FP_ROUND_AWAY,
269-
270-
/** Rounding over floating points. */
271-
FP_ROUND_POSITIVE,
272-
273-
/** Rounding over floating points. */
274-
FP_ROUND_NEGATIVE,
275-
276-
/** Rounding over floating points. */
277-
FP_ROUND_ZERO,
278-
279264
/** Rounding over floating points. */
280265
FP_ROUND_TO_INTEGRAL,
281266

src/org/sosy_lab/java_smt/basicimpl/AbstractFloatingPointFormulaManager.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.sosy_lab.java_smt.api.FloatingPointFormulaManager;
2323
import org.sosy_lab.java_smt.api.FloatingPointNumber.Sign;
2424
import org.sosy_lab.java_smt.api.FloatingPointRoundingMode;
25+
import org.sosy_lab.java_smt.api.FloatingPointRoundingModeFormula;
2526
import org.sosy_lab.java_smt.api.Formula;
2627
import org.sosy_lab.java_smt.api.FormulaType;
2728
import org.sosy_lab.java_smt.api.FormulaType.FloatingPointType;
@@ -60,6 +61,18 @@ private TFormulaInfo getRoundingMode(FloatingPointRoundingMode pFloatingPointRou
6061
return roundingModes.computeIfAbsent(pFloatingPointRoundingMode, this::getRoundingModeImpl);
6162
}
6263

64+
@Override
65+
public FloatingPointRoundingModeFormula makeRoundingMode(
66+
FloatingPointRoundingMode pRoundingMode) {
67+
return getFormulaCreator().encapsulateRoundingMode(getRoundingMode(pRoundingMode));
68+
}
69+
70+
@Override
71+
public FloatingPointRoundingMode fromRoundingModeFormula(
72+
FloatingPointRoundingModeFormula pRoundingModeFormula) {
73+
return getFormulaCreator().getRoundingMode(extractInfo(pRoundingModeFormula));
74+
}
75+
6376
protected FloatingPointFormula wrap(TFormulaInfo pTerm) {
6477
return getFormulaCreator().encapsulateFloatingPoint(pTerm);
6578
}

src/org/sosy_lab/java_smt/basicimpl/FormulaCreator.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.sosy_lab.java_smt.api.BooleanFormula;
3232
import org.sosy_lab.java_smt.api.EnumerationFormula;
3333
import org.sosy_lab.java_smt.api.FloatingPointFormula;
34+
import org.sosy_lab.java_smt.api.FloatingPointRoundingMode;
3435
import org.sosy_lab.java_smt.api.FloatingPointRoundingModeFormula;
3536
import org.sosy_lab.java_smt.api.Formula;
3637
import org.sosy_lab.java_smt.api.FormulaType;
@@ -134,6 +135,16 @@ public final TType getRegexType() {
134135
return regexType;
135136
}
136137

138+
public FloatingPointRoundingMode getRoundingMode(FloatingPointRoundingModeFormula f) {
139+
return getRoundingMode(extractInfo(f));
140+
}
141+
142+
@SuppressWarnings("unused")
143+
protected FloatingPointRoundingMode getRoundingMode(TFormulaInfo f) {
144+
throw new UnsupportedOperationException(
145+
"Floating point rounding modes are not supported by this solver.");
146+
}
147+
137148
public abstract TFormulaInfo makeVariable(TType type, String varName);
138149

139150
public BooleanFormula encapsulateBoolean(TFormulaInfo pTerm) {
@@ -160,6 +171,14 @@ protected FloatingPointFormula encapsulateFloatingPoint(TFormulaInfo pTerm) {
160171
return new FloatingPointFormulaImpl<>(pTerm);
161172
}
162173

174+
protected FloatingPointRoundingModeFormula encapsulateRoundingMode(TFormulaInfo pTerm) {
175+
checkArgument(
176+
getFormulaType(pTerm).isFloatingPointRoundingModeType(),
177+
"Floatingpoint rounding mode formula has unexpected type: %s",
178+
getFormulaType(pTerm));
179+
return new FloatingPointRoundingModeFormulaImpl<>(pTerm);
180+
}
181+
163182
protected <TI extends Formula, TE extends Formula> ArrayFormula<TI, TE> encapsulateArray(
164183
TFormulaInfo pTerm, FormulaType<TI> pIndexType, FormulaType<TE> pElementType) {
165184
checkArgument(

src/org/sosy_lab/java_smt/delegate/debugging/DebuggingFloatingPointFormulaManager.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.sosy_lab.java_smt.api.FloatingPointFormulaManager;
1818
import org.sosy_lab.java_smt.api.FloatingPointNumber.Sign;
1919
import org.sosy_lab.java_smt.api.FloatingPointRoundingMode;
20+
import org.sosy_lab.java_smt.api.FloatingPointRoundingModeFormula;
2021
import org.sosy_lab.java_smt.api.Formula;
2122
import org.sosy_lab.java_smt.api.FormulaType;
2223
import org.sosy_lab.java_smt.api.FormulaType.FloatingPointType;
@@ -31,6 +32,23 @@ public class DebuggingFloatingPointFormulaManager implements FloatingPointFormul
3132
debugging = pDebugging;
3233
}
3334

35+
@Override
36+
public FloatingPointRoundingModeFormula makeRoundingMode(
37+
FloatingPointRoundingMode pRoundingMode) {
38+
debugging.assertThreadLocal();
39+
FloatingPointRoundingModeFormula result = delegate.makeRoundingMode(pRoundingMode);
40+
debugging.addFormulaTerm(result);
41+
return result;
42+
}
43+
44+
@Override
45+
public FloatingPointRoundingMode fromRoundingModeFormula(
46+
FloatingPointRoundingModeFormula pRoundingModeFormula) {
47+
debugging.assertThreadLocal();
48+
debugging.assertFormulaInContext(pRoundingModeFormula);
49+
return delegate.fromRoundingModeFormula(pRoundingModeFormula);
50+
}
51+
3452
@Override
3553
public FloatingPointFormula makeNumber(double n, FloatingPointType type) {
3654
debugging.assertThreadLocal();

src/org/sosy_lab/java_smt/delegate/statistics/StatisticsFloatingPointFormulaManager.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.sosy_lab.java_smt.api.FloatingPointFormulaManager;
2020
import org.sosy_lab.java_smt.api.FloatingPointNumber.Sign;
2121
import org.sosy_lab.java_smt.api.FloatingPointRoundingMode;
22+
import org.sosy_lab.java_smt.api.FloatingPointRoundingModeFormula;
2223
import org.sosy_lab.java_smt.api.Formula;
2324
import org.sosy_lab.java_smt.api.FormulaType;
2425
import org.sosy_lab.java_smt.api.FormulaType.FloatingPointType;
@@ -34,6 +35,20 @@ class StatisticsFloatingPointFormulaManager implements FloatingPointFormulaManag
3435
stats = checkNotNull(pStats);
3536
}
3637

38+
@Override
39+
public FloatingPointRoundingModeFormula makeRoundingMode(
40+
FloatingPointRoundingMode pRoundingMode) {
41+
stats.fpOperations.getAndIncrement();
42+
return delegate.makeRoundingMode(pRoundingMode);
43+
}
44+
45+
@Override
46+
public FloatingPointRoundingMode fromRoundingModeFormula(
47+
FloatingPointRoundingModeFormula pRoundingModeFormula) {
48+
stats.fpOperations.getAndIncrement();
49+
return delegate.fromRoundingModeFormula(pRoundingModeFormula);
50+
}
51+
3752
@Override
3853
public FloatingPointFormula makeNumber(double pN, FloatingPointType pType) {
3954
stats.fpOperations.getAndIncrement();

src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedFloatingPointFormulaManager.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.sosy_lab.java_smt.api.FloatingPointFormulaManager;
2020
import org.sosy_lab.java_smt.api.FloatingPointNumber.Sign;
2121
import org.sosy_lab.java_smt.api.FloatingPointRoundingMode;
22+
import org.sosy_lab.java_smt.api.FloatingPointRoundingModeFormula;
2223
import org.sosy_lab.java_smt.api.Formula;
2324
import org.sosy_lab.java_smt.api.FormulaType;
2425
import org.sosy_lab.java_smt.api.FormulaType.FloatingPointType;
@@ -35,6 +36,22 @@ class SynchronizedFloatingPointFormulaManager implements FloatingPointFormulaMan
3536
sync = checkNotNull(pSync);
3637
}
3738

39+
@Override
40+
public FloatingPointRoundingModeFormula makeRoundingMode(
41+
FloatingPointRoundingMode pRoundingMode) {
42+
synchronized (sync) {
43+
return delegate.makeRoundingMode(pRoundingMode);
44+
}
45+
}
46+
47+
@Override
48+
public FloatingPointRoundingMode fromRoundingModeFormula(
49+
FloatingPointRoundingModeFormula pRoundingModeFormula) {
50+
synchronized (sync) {
51+
return delegate.fromRoundingModeFormula(pRoundingModeFormula);
52+
}
53+
}
54+
3855
@Override
3956
public FloatingPointFormula makeNumber(double pN, FloatingPointType pType) {
4057
synchronized (sync) {

0 commit comments

Comments
 (0)