Skip to content

Commit 99a20b0

Browse files
committed
add new API methods for FP_SQRT, FP_MAX and FP_MIN.
All FP-supporting solvers have this operation, thus we can provide it. For users, it might be more convenient to use these methods than to check for special values NaN, -Inf and Inf.
1 parent b858776 commit 99a20b0

11 files changed

+142
-0
lines changed

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

+8
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,14 @@ FloatingPointFormula castFrom(
142142

143143
FloatingPointFormula abs(FloatingPointFormula number);
144144

145+
FloatingPointFormula max(FloatingPointFormula number1, FloatingPointFormula number2);
146+
147+
FloatingPointFormula min(FloatingPointFormula number1, FloatingPointFormula number2);
148+
149+
FloatingPointFormula sqrt(FloatingPointFormula number);
150+
151+
FloatingPointFormula sqrt(FloatingPointFormula number, FloatingPointRoundingMode roundingMode);
152+
145153
FloatingPointFormula add(FloatingPointFormula number1, FloatingPointFormula number2);
146154

147155
FloatingPointFormula add(

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

+9
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,15 @@ public enum FunctionDeclarationKind {
200200
/** Absolute value of a floating point. */
201201
FP_ABS,
202202

203+
/** Maximum of two floating points. */
204+
FP_MAX,
205+
206+
/** Minimum of two floating points. */
207+
FP_MIN,
208+
209+
/** Square root of a floating point. */
210+
FP_SQRT,
211+
203212
/** Subtraction over floating points. */
204213
FP_SUB,
205214

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

+27
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,33 @@ public FloatingPointFormula abs(FloatingPointFormula pNumber) {
258258

259259
protected abstract TFormulaInfo abs(TFormulaInfo pParam1);
260260

261+
@Override
262+
public FloatingPointFormula max(FloatingPointFormula pNumber1, FloatingPointFormula pNumber2) {
263+
return wrap(max(extractInfo(pNumber1), extractInfo(pNumber2)));
264+
}
265+
266+
protected abstract TFormulaInfo max(TFormulaInfo pParam1, TFormulaInfo pParam2);
267+
268+
@Override
269+
public FloatingPointFormula min(FloatingPointFormula pNumber1, FloatingPointFormula pNumber2) {
270+
return wrap(min(extractInfo(pNumber1), extractInfo(pNumber2)));
271+
}
272+
273+
protected abstract TFormulaInfo min(TFormulaInfo pParam1, TFormulaInfo pParam2);
274+
275+
@Override
276+
public FloatingPointFormula sqrt(FloatingPointFormula pNumber) {
277+
return wrap(sqrt(extractInfo(pNumber), getDefaultRoundingMode()));
278+
}
279+
280+
@Override
281+
public FloatingPointFormula sqrt(
282+
FloatingPointFormula number, FloatingPointRoundingMode pFloatingPointRoundingMode) {
283+
return wrap(sqrt(extractInfo(number), getRoundingMode(pFloatingPointRoundingMode)));
284+
}
285+
286+
protected abstract TFormulaInfo sqrt(TFormulaInfo pNumber, TFormulaInfo pRoundingMode);
287+
261288
@Override
262289
public FloatingPointFormula add(FloatingPointFormula pNumber1, FloatingPointFormula pNumber2) {
263290
TFormulaInfo param1 = extractInfo(pNumber1);

src/org/sosy_lab/java_smt/solvers/cvc4/CVC4FloatingPointFormulaManager.java

+15
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,21 @@ protected Expr abs(Expr pParam1) {
251251
return exprManager.mkExpr(Kind.FLOATINGPOINT_ABS, pParam1);
252252
}
253253

254+
@Override
255+
protected Expr max(Expr pParam1, Expr pParam2) {
256+
return exprManager.mkExpr(Kind.FLOATINGPOINT_MAX, pParam1, pParam2);
257+
}
258+
259+
@Override
260+
protected Expr min(Expr pParam1, Expr pParam2) {
261+
return exprManager.mkExpr(Kind.FLOATINGPOINT_MIN, pParam1, pParam2);
262+
}
263+
264+
@Override
265+
protected Expr sqrt(Expr pParam1, Expr pRoundingMode) {
266+
return exprManager.mkExpr(Kind.FLOATINGPOINT_SQRT, pRoundingMode, pParam1);
267+
}
268+
254269
@Override
255270
protected Expr add(Expr pParam1, Expr pParam2, Expr pRoundingMode) {
256271
return exprManager.mkExpr(Kind.FLOATINGPOINT_PLUS, pRoundingMode, pParam1, pParam2);

src/org/sosy_lab/java_smt/solvers/cvc4/CVC4FormulaCreator.java

+3
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,9 @@ public <R> R visit(FormulaVisitor<R> visitor, Formula formula, final Expr f) {
371371
.put(Kind.FLOATINGPOINT_ISZ, FunctionDeclarationKind.FP_IS_ZERO)
372372
.put(Kind.FLOATINGPOINT_EQ, FunctionDeclarationKind.FP_EQ)
373373
.put(Kind.FLOATINGPOINT_ABS, FunctionDeclarationKind.FP_ABS)
374+
.put(Kind.FLOATINGPOINT_MAX, FunctionDeclarationKind.FP_MAX)
375+
.put(Kind.FLOATINGPOINT_MIN, FunctionDeclarationKind.FP_MIN)
376+
.put(Kind.FLOATINGPOINT_SQRT, FunctionDeclarationKind.FP_SQRT)
374377
.put(Kind.FLOATINGPOINT_PLUS, FunctionDeclarationKind.FP_ADD)
375378
.put(Kind.FLOATINGPOINT_SUB, FunctionDeclarationKind.FP_SUB)
376379
.put(Kind.FLOATINGPOINT_MULT, FunctionDeclarationKind.FP_MUL)

src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5FloatingPointFormulaManager.java

+18
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_iszero;
3535
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_leq;
3636
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_lt;
37+
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_max;
38+
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_min;
3739
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_minus;
3840
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_minus_inf;
3941
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_nan;
@@ -46,6 +48,7 @@
4648
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_roundingmode_nearest_even;
4749
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_roundingmode_plus_inf;
4850
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_roundingmode_zero;
51+
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_sqrt;
4952
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_times;
5053
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_fp_to_bv;
5154
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_uf;
@@ -220,6 +223,21 @@ protected Long abs(Long pNumber) {
220223
return msat_make_fp_abs(mathsatEnv, pNumber);
221224
}
222225

226+
@Override
227+
protected Long max(Long pNumber1, Long pNumber2) {
228+
return msat_make_fp_max(mathsatEnv, pNumber1, pNumber2);
229+
}
230+
231+
@Override
232+
protected Long min(Long pNumber1, Long pNumber2) {
233+
return msat_make_fp_min(mathsatEnv, pNumber1, pNumber2);
234+
}
235+
236+
@Override
237+
protected Long sqrt(Long pNumber, Long pRoundingMode) {
238+
return msat_make_fp_sqrt(mathsatEnv, pRoundingMode, pNumber);
239+
}
240+
223241
@Override
224242
protected Long add(Long pNumber1, Long pNumber2, Long pRoundingMode) {
225243
return msat_make_fp_plus(mathsatEnv, pRoundingMode, pNumber1, pNumber2);

src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5FormulaCreator.java

+9
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,12 @@
6464
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_FP_ISZERO;
6565
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_FP_LE;
6666
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_FP_LT;
67+
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_FP_MAX;
68+
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_FP_MIN;
6769
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_FP_MUL;
6870
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_FP_NEG;
6971
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_FP_ROUND_TO_INT;
72+
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_FP_SQRT;
7073
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_FP_SUB;
7174
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_FP_TO_BV;
7275
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.MSAT_TAG_IFF;
@@ -435,6 +438,12 @@ private FunctionDeclarationKind getDeclarationKind(long pF) {
435438
return FunctionDeclarationKind.FP_NEG;
436439
case MSAT_TAG_FP_ABS:
437440
return FunctionDeclarationKind.FP_ABS;
441+
case MSAT_TAG_FP_MAX:
442+
return FunctionDeclarationKind.FP_MAX;
443+
case MSAT_TAG_FP_MIN:
444+
return FunctionDeclarationKind.FP_MIN;
445+
case MSAT_TAG_FP_SQRT:
446+
return FunctionDeclarationKind.FP_SQRT;
438447
case MSAT_TAG_FP_ADD:
439448
return FunctionDeclarationKind.FP_ADD;
440449
case MSAT_TAG_FP_SUB:

src/org/sosy_lab/java_smt/solvers/z3/Z3FloatingPointFormulaManager.java

+15
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,21 @@ protected Long abs(Long pNumber) {
191191
return Native.mkFpaAbs(z3context, pNumber);
192192
}
193193

194+
@Override
195+
protected Long max(Long pNumber1, Long pNumber2) {
196+
return Native.mkFpaMax(z3context, pNumber1, pNumber2);
197+
}
198+
199+
@Override
200+
protected Long min(Long pNumber1, Long pNumber2) {
201+
return Native.mkFpaMin(z3context, pNumber1, pNumber2);
202+
}
203+
204+
@Override
205+
protected Long sqrt(Long pNumber, Long pRoundingMode) {
206+
return Native.mkFpaSqrt(z3context, pRoundingMode, pNumber);
207+
}
208+
194209
@Override
195210
protected Long add(Long pNumber1, Long pNumber2, Long pRoundingMode) {
196211
return Native.mkFpaAdd(z3context, pRoundingMode, pNumber1, pNumber2);

src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java

+6
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,12 @@ private FunctionDeclarationKind getDeclarationKind(long f) {
565565
return FunctionDeclarationKind.FP_NEG;
566566
case Z3_OP_FPA_ABS:
567567
return FunctionDeclarationKind.FP_ABS;
568+
case Z3_OP_FPA_MAX:
569+
return FunctionDeclarationKind.FP_MAX;
570+
case Z3_OP_FPA_MIN:
571+
return FunctionDeclarationKind.FP_MIN;
572+
case Z3_OP_FPA_SQRT:
573+
return FunctionDeclarationKind.FP_SQRT;
568574
case Z3_OP_FPA_SUB:
569575
return FunctionDeclarationKind.FP_SUB;
570576
case Z3_OP_FPA_ADD:

src/org/sosy_lab/java_smt/test/FloatingPointFormulaManagerTest.java

+28
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,16 @@ public void infinityOrdering() throws SolverException, InterruptedException {
185185
BooleanFormula order3 = fpmgr.greaterThan(posInf, negInf);
186186

187187
assertThatFormula(bmgr.and(order1, order2, order3)).isTautological();
188+
189+
assertThatFormula(fpmgr.equalWithFPSemantics(fpmgr.max(posInf, zero), posInf)).isTautological();
190+
assertThatFormula(fpmgr.equalWithFPSemantics(fpmgr.max(posInf, negInf), posInf))
191+
.isTautological();
192+
assertThatFormula(fpmgr.equalWithFPSemantics(fpmgr.max(negInf, zero), zero)).isTautological();
193+
194+
assertThatFormula(fpmgr.equalWithFPSemantics(fpmgr.min(posInf, zero), zero)).isTautological();
195+
assertThatFormula(fpmgr.equalWithFPSemantics(fpmgr.min(posInf, negInf), negInf))
196+
.isTautological();
197+
assertThatFormula(fpmgr.equalWithFPSemantics(fpmgr.min(negInf, zero), negInf)).isTautological();
188198
}
189199

190200
@Test
@@ -198,6 +208,24 @@ public void infinityVariableOrdering() throws SolverException, InterruptedExcept
198208
assertThatFormula(bmgr.or(varIsNan, bmgr.and(order1, order2))).isTautological();
199209
}
200210

211+
@Test
212+
public void sqrt() throws SolverException, InterruptedException {
213+
for (double d : new double[] {0.25, 1, 2, 4, 9, 15, 1234, 1000000}) {
214+
assertThatFormula(
215+
fpmgr.equalWithFPSemantics(
216+
fpmgr.sqrt(fpmgr.makeNumber(d * d, doublePrecType)),
217+
fpmgr.makeNumber(d, doublePrecType)))
218+
.isTautological();
219+
assertThatFormula(
220+
fpmgr.equalWithFPSemantics(
221+
fpmgr.sqrt(fpmgr.makeNumber(d, doublePrecType)),
222+
fpmgr.makeNumber(Math.sqrt(d), doublePrecType)))
223+
.isTautological();
224+
assertThatFormula(fpmgr.isNaN(fpmgr.sqrt(fpmgr.makeNumber(-d, doublePrecType))))
225+
.isTautological();
226+
}
227+
}
228+
201229
@Test
202230
public void specialValueFunctions() throws SolverException, InterruptedException {
203231
assertThatFormula(fpmgr.isInfinity(posInf)).isTautological();

src/org/sosy_lab/java_smt/test/SolverVisitorTest.java

+4
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ public void floatMoreVisit() {
191191
requireBitvectors();
192192
FloatingPointType fp = FormulaType.getSinglePrecisionFloatingPointType();
193193
FloatingPointFormula x = fpmgr.makeVariable("x", fp);
194+
FloatingPointFormula y = fpmgr.makeVariable("x", fp);
194195
BitvectorFormula z = bvmgr.makeVariable(32, "z");
195196

196197
checkKind(
@@ -206,6 +207,9 @@ public void floatMoreVisit() {
206207
checkKind(fpmgr.isSubnormal(x), FunctionDeclarationKind.FP_IS_SUBNORMAL);
207208
checkKind(fpmgr.isZero(x), FunctionDeclarationKind.FP_IS_ZERO);
208209
checkKind(fpmgr.abs(x), FunctionDeclarationKind.FP_ABS);
210+
checkKind(fpmgr.max(x, y), FunctionDeclarationKind.FP_MAX);
211+
checkKind(fpmgr.min(x, y), FunctionDeclarationKind.FP_MIN);
212+
checkKind(fpmgr.sqrt(x), FunctionDeclarationKind.FP_SQRT);
209213
if (Solvers.CVC4 != solverToUse()) { // CVC4 does not support this operation
210214
checkKind(fpmgr.toIeeeBitvector(x), FunctionDeclarationKind.FP_AS_IEEEBV);
211215
}

0 commit comments

Comments
 (0)