diff --git a/src/org/sosy_lab/java_smt/SolverContextFactory.java b/src/org/sosy_lab/java_smt/SolverContextFactory.java index 34c547ae28..cda52a0f09 100644 --- a/src/org/sosy_lab/java_smt/SolverContextFactory.java +++ b/src/org/sosy_lab/java_smt/SolverContextFactory.java @@ -30,6 +30,7 @@ import org.sosy_lab.java_smt.delegate.logging.LoggingSolverContext; import org.sosy_lab.java_smt.delegate.statistics.StatisticsSolverContext; import org.sosy_lab.java_smt.delegate.synchronize.SynchronizedSolverContext; +import org.sosy_lab.java_smt.delegate.trace.TraceSolverContext; import org.sosy_lab.java_smt.solvers.bitwuzla.BitwuzlaSolverContext; import org.sosy_lab.java_smt.solvers.boolector.BoolectorSolverContext; import org.sosy_lab.java_smt.solvers.cvc4.CVC4SolverContext; @@ -95,6 +96,11 @@ public enum Solvers { @Option(secure = true, description = "Apply additional checks to catch common user errors.") private boolean useDebugMode = false; + @Option( + secure = true, + description = "Enable API tracing to record all calls to the JavaSMT library") + private boolean trace = false; + @Option( secure = true, description = "Counts all operations and interactions towards the SMT solver.") @@ -230,6 +236,9 @@ public SolverContext generateContext(Solvers solverToCreate) if (useDebugMode) { context = new DebuggingSolverContext(solverToCreate, config, context); } + if (trace) { + context = new TraceSolverContext(solverToCreate, config, context); + } if (collectStatistics) { // statistics need to be the most outer wrapping layer. context = new StatisticsSolverContext(context); diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceArrayFormulaManager.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceArrayFormulaManager.java new file mode 100644 index 0000000000..d641eea34f --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceArrayFormulaManager.java @@ -0,0 +1,93 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import org.sosy_lab.java_smt.api.ArrayFormula; +import org.sosy_lab.java_smt.api.ArrayFormulaManager; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.Formula; +import org.sosy_lab.java_smt.api.FormulaType; + +@SuppressWarnings("MethodTypeParameterName") +public class TraceArrayFormulaManager implements ArrayFormulaManager { + private final ArrayFormulaManager delegate; + private final TraceLogger logger; + + TraceArrayFormulaManager(ArrayFormulaManager pDelegate, TraceLogger pLogger) { + delegate = pDelegate; + logger = pLogger; + } + + @Override + public TE select( + ArrayFormula pArray, TI pIndex) { + return logger.logDef( + "mgr.getArrayFormulaManager()", + String.format("select(%s, %s)", logger.toVariable(pArray), logger.toVariable(pIndex)), + () -> delegate.select(pArray, pIndex)); + } + + @Override + public ArrayFormula store( + ArrayFormula pArray, TI pIndex, TE pValue) { + return logger.logDef( + "mgr.getArrayFormulaManager()", + String.format( + "store(%s, %s, %s)", + logger.toVariable(pArray), logger.toVariable(pIndex), logger.toVariable(pValue)), + () -> delegate.store(pArray, pIndex, pValue)); + } + + @Override + public < + TI extends Formula, + TE extends Formula, + FTI extends FormulaType, + FTE extends FormulaType> + ArrayFormula makeArray(String pName, FTI pIndexType, FTE pElementType) { + return logger.logDef( + "mgr.getArrayFormulaManager()", + String.format( + "makeArray(\"%s\", %s, %s)", + pName, logger.printFormulaType(pIndexType), logger.printFormulaType(pElementType)), + () -> delegate.makeArray(pName, pIndexType, pElementType)); + } + + @Override + public < + TI extends Formula, + TE extends Formula, + FTI extends FormulaType, + FTE extends FormulaType> + ArrayFormula makeArray(FTI pIndexType, FTE pElementType, TE defaultElement) { + throw new UnsupportedOperationException(); + } + + @Override + public BooleanFormula equivalence( + ArrayFormula pArray1, ArrayFormula pArray2) { + return logger.logDef( + "mgr.getArrayFormulaManager()", + String.format( + "equivalence(%s, %s)", logger.toVariable(pArray1), logger.toVariable(pArray2)), + () -> delegate.equivalence(pArray1, pArray2)); + } + + @Override + public FormulaType getIndexType(ArrayFormula pArray) { + return delegate.getIndexType(pArray); + } + + @Override + public FormulaType getElementType(ArrayFormula pArray) { + return delegate.getElementType(pArray); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceBasicProverEnvironment.java new file mode 100644 index 0000000000..dfcb804b96 --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceBasicProverEnvironment.java @@ -0,0 +1,93 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.java_smt.api.BasicProverEnvironment; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.Model; +import org.sosy_lab.java_smt.api.SolverException; + +public class TraceBasicProverEnvironment implements BasicProverEnvironment { + private final BasicProverEnvironment delegate; + private final TraceLogger logger; + + TraceBasicProverEnvironment(BasicProverEnvironment pDelegate, TraceLogger pLogger) { + delegate = pDelegate; + logger = pLogger; + } + + @Override + public void pop() { + logger.logStmt(logger.toVariable(this), "pop()", delegate::pop); + } + + @Override + public @Nullable T addConstraint(BooleanFormula constraint) throws InterruptedException { + return logger.logDef( + logger.toVariable(this), + String.format("addConstraint(%s)", logger.toVariable(constraint)), + () -> delegate.addConstraint(constraint)); + } + + @Override + public void push() throws InterruptedException { + logger.logStmt(logger.toVariable(this), "push()", delegate::push); + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public boolean isUnsat() throws SolverException, InterruptedException { + return logger.logDef(logger.toVariable(this), "isUnsat()", delegate::isUnsat); + } + + @Override + public boolean isUnsatWithAssumptions(Collection assumptions) + throws SolverException, InterruptedException { + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("resource") + @Override + public Model getModel() throws SolverException { + return logger.logDef( + logger.toVariable(this), "getModel()", () -> new TraceModel(delegate.getModel(), logger)); + } + + @Override + public List getUnsatCore() { + throw new UnsupportedOperationException(); + } + + @Override + public Optional> unsatCoreOverAssumptions( + Collection assumptions) throws SolverException, InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public void close() { + logger.logStmt(logger.toVariable(this), "close()", delegate::close); + } + + @Override + public R allSat(AllSatCallback callback, List important) + throws InterruptedException, SolverException { + throw new UnsupportedOperationException(); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceBitvectorFormulaManager.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceBitvectorFormulaManager.java new file mode 100644 index 0000000000..a247ec978b --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceBitvectorFormulaManager.java @@ -0,0 +1,317 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import com.google.common.base.Joiner; +import com.google.common.collect.FluentIterable; +import java.math.BigInteger; +import java.util.List; +import org.sosy_lab.java_smt.api.BitvectorFormula; +import org.sosy_lab.java_smt.api.BitvectorFormulaManager; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.FormulaType.BitvectorType; +import org.sosy_lab.java_smt.api.NumeralFormula.IntegerFormula; + +public class TraceBitvectorFormulaManager implements BitvectorFormulaManager { + private final BitvectorFormulaManager delegate; + private final TraceLogger logger; + + TraceBitvectorFormulaManager(BitvectorFormulaManager pDelegate, TraceLogger pLogger) { + delegate = pDelegate; + logger = pLogger; + } + + @Override + public BitvectorFormula makeBitvector(int length, long pI) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("makeBitvector(%s, %s)", length, pI), + () -> delegate.makeBitvector(length, pI)); + } + + @Override + public BitvectorFormula makeBitvector(int length, BigInteger pI) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("makeBitvector(%s, new BigInteger(\"%s\"))", length, pI), + () -> delegate.makeBitvector(length, pI)); + } + + @Override + public BitvectorFormula makeBitvector(int length, IntegerFormula pI) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("makeBitvector(%s, %s)", length, logger.toVariable(pI)), + () -> delegate.makeBitvector(length, pI)); + } + + @Override + public IntegerFormula toIntegerFormula(BitvectorFormula pI, boolean signed) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("toIntegerFormula(%s, %s)", logger.toVariable(pI), signed), + () -> delegate.toIntegerFormula(pI, signed)); + } + + @Override + public BitvectorFormula makeVariable(int length, String pVar) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("makeVariable(%s, \"%s\")", length, pVar), + () -> delegate.makeVariable(length, pVar)); + } + + @Override + public BitvectorFormula makeVariable(BitvectorType type, String pVar) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("makeVariable(%s, \"%s\")", logger.printFormulaType(type), pVar), + () -> delegate.makeVariable(type, pVar)); + } + + @Override + public int getLength(BitvectorFormula number) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("getLength(%s)", logger.toVariable(number)), + () -> delegate.getLength(number)); + } + + @Override + public BitvectorFormula negate(BitvectorFormula number) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("negate(%s)", logger.toVariable(number)), + () -> delegate.negate(number)); + } + + @Override + public BitvectorFormula add(BitvectorFormula number1, BitvectorFormula number2) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("add(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.add(number1, number2)); + } + + @Override + public BitvectorFormula subtract(BitvectorFormula number1, BitvectorFormula number2) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("subtract(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.subtract(number1, number2)); + } + + @Override + public BitvectorFormula divide( + BitvectorFormula dividend, BitvectorFormula divisor, boolean signed) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format( + "divide(%s, %s, %s)", logger.toVariable(dividend), logger.toVariable(divisor), signed), + () -> delegate.divide(dividend, divisor, signed)); + } + + @Override + public BitvectorFormula smodulo(BitvectorFormula dividend, BitvectorFormula divisor) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("smodulo(%s, %s)", logger.toVariable(dividend), logger.toVariable(dividend)), + () -> delegate.smodulo(dividend, divisor)); + } + + @Override + public BitvectorFormula remainder( + BitvectorFormula dividend, BitvectorFormula divisor, boolean signed) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format( + "remainder(%s, %s, %s)", + logger.toVariable(dividend), logger.toVariable(divisor), signed), + () -> delegate.remainder(dividend, divisor, signed)); + } + + @Override + public BitvectorFormula multiply(BitvectorFormula number1, BitvectorFormula number2) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("multiply(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.multiply(number1, number2)); + } + + @Override + public BooleanFormula equal(BitvectorFormula number1, BitvectorFormula number2) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("equal(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.equal(number1, number2)); + } + + @Override + public BooleanFormula greaterThan( + BitvectorFormula number1, BitvectorFormula number2, boolean signed) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format( + "greaterThan(%s, %s, %s)", + logger.toVariable(number1), logger.toVariable(number2), signed), + () -> delegate.greaterThan(number1, number2, signed)); + } + + @Override + public BooleanFormula greaterOrEquals( + BitvectorFormula number1, BitvectorFormula number2, boolean signed) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format( + "greaterOrEquals(%s, %s, %s)", + logger.toVariable(number1), logger.toVariable(number2), signed), + () -> delegate.greaterOrEquals(number1, number2, signed)); + } + + @Override + public BooleanFormula lessThan( + BitvectorFormula number1, BitvectorFormula number2, boolean signed) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format( + "lessThan(%s, %s, %s)", logger.toVariable(number1), logger.toVariable(number2), signed), + () -> delegate.lessThan(number1, number2, signed)); + } + + @Override + public BooleanFormula lessOrEquals( + BitvectorFormula number1, BitvectorFormula number2, boolean signed) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format( + "lessOrEquals(%s, %s, %s)", + logger.toVariable(number1), logger.toVariable(number2), signed), + () -> delegate.lessOrEquals(number1, number2, signed)); + } + + @Override + public BitvectorFormula not(BitvectorFormula bits) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("not(%s)", logger.toVariable(bits)), + () -> delegate.not(bits)); + } + + @Override + public BitvectorFormula and(BitvectorFormula bits1, BitvectorFormula bits2) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("and(%s, %s)", logger.toVariable(bits1), logger.toVariable(bits2)), + () -> delegate.and(bits1, bits2)); + } + + @Override + public BitvectorFormula or(BitvectorFormula bits1, BitvectorFormula bits2) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("or(%s, %s)", logger.toVariable(bits1), logger.toVariable(bits2)), + () -> delegate.or(bits1, bits2)); + } + + @Override + public BitvectorFormula xor(BitvectorFormula bits1, BitvectorFormula bits2) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("xor(%s, %s)", logger.toVariable(bits1), logger.toVariable(bits2)), + () -> delegate.xor(bits1, bits2)); + } + + @Override + public BitvectorFormula shiftRight( + BitvectorFormula number, BitvectorFormula toShift, boolean signed) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format( + "shiftRight(%s, %s, %s)", + logger.toVariable(number), logger.toVariable(toShift), signed), + () -> delegate.shiftRight(number, toShift, signed)); + } + + @Override + public BitvectorFormula shiftLeft(BitvectorFormula number, BitvectorFormula toShift) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("shiftLeft(%s, %s)", logger.toVariable(number), logger.toVariable(toShift)), + () -> delegate.shiftLeft(number, toShift)); + } + + @Override + public BitvectorFormula rotateLeft(BitvectorFormula number, int toRotate) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("rotateLeft(%s, %s)", logger.toVariable(number), toRotate), + () -> delegate.rotateLeft(number, toRotate)); + } + + @Override + public BitvectorFormula rotateLeft(BitvectorFormula number, BitvectorFormula toRotate) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("rotateLeft(%s, %s)", logger.toVariable(number), logger.toVariable(toRotate)), + () -> delegate.rotateLeft(number, toRotate)); + } + + @Override + public BitvectorFormula rotateRight(BitvectorFormula number, int toRotate) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("rotateRight(%s, %s)", logger.toVariable(number), toRotate), + () -> delegate.rotateRight(number, toRotate)); + } + + @Override + public BitvectorFormula rotateRight(BitvectorFormula number, BitvectorFormula toRotate) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format( + "rotateRight(%s, %s)", logger.toVariable(number), logger.toVariable(toRotate)), + () -> delegate.rotateRight(number, toRotate)); + } + + @Override + public BitvectorFormula concat(BitvectorFormula prefix, BitvectorFormula suffix) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("concat(%s, %s)", logger.toVariable(prefix), logger.toVariable(prefix)), + () -> delegate.concat(prefix, suffix)); + } + + @Override + public BitvectorFormula extract(BitvectorFormula number, int msb, int lsb) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("extract(%s, %s, %s)", logger.toVariable(number), msb, lsb), + () -> delegate.extract(number, msb, lsb)); + } + + @Override + public BitvectorFormula extend(BitvectorFormula number, int extensionBits, boolean signed) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format("extend(%s, %s, %s)", logger.toVariable(number), extensionBits, signed), + () -> delegate.extend(number, extensionBits, signed)); + } + + @Override + public BooleanFormula distinct(List pBits) { + return logger.logDef( + "mgr.getBitvectorFormulaManager()", + String.format( + "distinct(ImmutableList.of(%s))", + FluentIterable.from(pBits).transform(logger::toVariable).join(Joiner.on(", "))), + () -> delegate.distinct(pBits)); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceBooleanFormulaManager.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceBooleanFormulaManager.java new file mode 100644 index 0000000000..78ae819fe0 --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceBooleanFormulaManager.java @@ -0,0 +1,188 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Set; +import java.util.stream.Collector; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.BooleanFormulaManager; +import org.sosy_lab.java_smt.api.Formula; +import org.sosy_lab.java_smt.api.visitors.BooleanFormulaTransformationVisitor; +import org.sosy_lab.java_smt.api.visitors.BooleanFormulaVisitor; +import org.sosy_lab.java_smt.api.visitors.TraversalProcess; + +public class TraceBooleanFormulaManager implements BooleanFormulaManager { + private final BooleanFormulaManager delegate; + private final TraceLogger logger; + + TraceBooleanFormulaManager(BooleanFormulaManager pDelegate, TraceLogger pLogger) { + delegate = pDelegate; + logger = pLogger; + } + + @Override + public BooleanFormula makeTrue() { + return logger.logDef("mgr.getBooleanFormulaManager()", "makeTrue()", delegate::makeTrue); + } + + @Override + public BooleanFormula makeFalse() { + return logger.logDef("mgr.getBooleanFormulaManager()", "makeFalse()", delegate::makeFalse); + } + + @Override + public BooleanFormula makeVariable(String pVar) { + return logger.logDef( + "mgr.getBooleanFormulaManager()", + String.format("makeVariable(\"%s\")", pVar), + () -> delegate.makeVariable(pVar)); + } + + @Override + public BooleanFormula equivalence(BooleanFormula formula1, BooleanFormula formula2) { + return logger.logDef( + "mgr.getBooleanFormulaManager()", + String.format( + "equivalence(%s, %s)", logger.toVariable(formula1), logger.toVariable(formula2)), + () -> delegate.equivalence(formula1, formula2)); + } + + @Override + public BooleanFormula implication(BooleanFormula formula1, BooleanFormula formula2) { + return logger.logDef( + "mgr.getBooleanFormulaManager()", + String.format( + "implication(%s, %s)", logger.toVariable(formula1), logger.toVariable(formula2)), + () -> delegate.implication(formula1, formula2)); + } + + @Override + public boolean isTrue(BooleanFormula formula) { + return logger.logDef( + "mgr.getBooleanFormulaManager()", + String.format("isTrue(%s)", logger.toVariable(formula)), + () -> delegate.isTrue(formula)); + } + + @Override + public boolean isFalse(BooleanFormula formula) { + return logger.logDef( + "mgr.getBooleanFormulaManager()", + String.format("isFalse(%s)", logger.toVariable(formula)), + () -> delegate.isFalse(formula)); + } + + @Override + public T ifThenElse(BooleanFormula cond, T f1, T f2) { + return logger.logDef( + "mgr.getBooleanFormulaManager()", + String.format( + "ifThenElse(%s, %s, %s)", + logger.toVariable(cond), logger.toVariable(f1), logger.toVariable(f2)), + () -> delegate.ifThenElse(cond, f1, f2)); + } + + @Override + public BooleanFormula not(BooleanFormula formula) { + return logger.logDef( + "mgr.getBooleanFormulaManager()", + String.format("not(%s)", logger.toVariable(formula)), + () -> delegate.not(formula)); + } + + @Override + public BooleanFormula and(BooleanFormula formula1, BooleanFormula formula2) { + return logger.logDef( + "mgr.getBooleanFormulaManager()", + String.format("and(%s, %s)", logger.toVariable(formula1), logger.toVariable(formula2)), + () -> delegate.and(formula1, formula2)); + } + + @Override + public BooleanFormula and(Collection bits) { + BooleanFormula f = makeTrue(); + for (BooleanFormula bf : bits) { + f = and(bf, f); + } + return f; + } + + @Override + public BooleanFormula and(BooleanFormula... bits) { + return and(Arrays.asList(bits)); + } + + @Override + public Collector toConjunction() { + throw new UnsupportedOperationException(); + } + + @Override + public BooleanFormula or(BooleanFormula formula1, BooleanFormula formula2) { + return logger.logDef( + "mgr.getBooleanFormulaManager()", + String.format("or(%s, %s)", logger.toVariable(formula1), logger.toVariable(formula2)), + () -> delegate.or(formula1, formula2)); + } + + @Override + public BooleanFormula or(Collection bits) { + BooleanFormula f = makeFalse(); + for (BooleanFormula bf : bits) { + f = or(bf, f); + } + return f; + } + + @Override + public BooleanFormula or(BooleanFormula... bits) { + return or(Arrays.asList(bits)); + } + + @Override + public Collector toDisjunction() { + throw new UnsupportedOperationException(); + } + + @Override + public BooleanFormula xor(BooleanFormula bits1, BooleanFormula bits2) { + throw new UnsupportedOperationException(); + } + + @Override + public R visit(BooleanFormula pFormula, BooleanFormulaVisitor visitor) { + throw new UnsupportedOperationException(); + } + + @Override + public void visitRecursively( + BooleanFormula f, BooleanFormulaVisitor rFormulaVisitor) { + throw new UnsupportedOperationException(); + } + + @Override + public BooleanFormula transformRecursively( + BooleanFormula f, BooleanFormulaTransformationVisitor pVisitor) { + throw new UnsupportedOperationException(); + } + + @Override + public Set toConjunctionArgs(BooleanFormula f, boolean flatten) { + throw new UnsupportedOperationException(); + } + + @Override + public Set toDisjunctionArgs(BooleanFormula f, boolean flatten) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceFloatingPointFormulaManager.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceFloatingPointFormulaManager.java new file mode 100644 index 0000000000..4d4746caff --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceFloatingPointFormulaManager.java @@ -0,0 +1,451 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import java.math.BigDecimal; +import java.math.BigInteger; +import org.sosy_lab.common.rationals.Rational; +import org.sosy_lab.java_smt.api.BitvectorFormula; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.FloatingPointFormula; +import org.sosy_lab.java_smt.api.FloatingPointFormulaManager; +import org.sosy_lab.java_smt.api.FloatingPointNumber.Sign; +import org.sosy_lab.java_smt.api.FloatingPointRoundingMode; +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; + +public class TraceFloatingPointFormulaManager implements FloatingPointFormulaManager { + private final FloatingPointFormulaManager delegate; + private final TraceLogger logger; + + public TraceFloatingPointFormulaManager( + FloatingPointFormulaManager pDelegate, TraceLogger pLogger) { + delegate = pDelegate; + logger = pLogger; + } + + @Override + public FloatingPointFormula makeNumber(double n, FloatingPointType type) { + return makeNumber(n, type, FloatingPointRoundingMode.NEAREST_TIES_TO_EVEN); + } + + private String printRoundingMode(FloatingPointRoundingMode pRoundingMode) { + return "FloatingPointRoundingMode." + pRoundingMode.name(); + } + + @Override + public FloatingPointFormula makeNumber( + double n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "makeNumber(%s, %s, %s)", + n, logger.printFormulaType(type), printRoundingMode(pFloatingPointRoundingMode)), + () -> delegate.makeNumber(n, type, pFloatingPointRoundingMode)); + } + + @Override + public FloatingPointFormula makeNumber(BigDecimal n, FloatingPointType type) { + return makeNumber(n, type, FloatingPointRoundingMode.NEAREST_TIES_AWAY); + } + + @Override + public FloatingPointFormula makeNumber( + BigDecimal n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode) { + throw new UnsupportedOperationException(); + } + + @Override + public FloatingPointFormula makeNumber(String n, FloatingPointType type) { + return makeNumber(n, type, FloatingPointRoundingMode.NEAREST_TIES_TO_EVEN); + } + + @Override + public FloatingPointFormula makeNumber( + String n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "makeNumber(\"%s\", %s, %s)", + n, logger.printFormulaType(type), printRoundingMode(pFloatingPointRoundingMode)), + () -> delegate.makeNumber(n, type, pFloatingPointRoundingMode)); + } + + @Override + public FloatingPointFormula makeNumber(Rational n, FloatingPointType type) { + throw new UnsupportedOperationException(); + } + + @Override + public FloatingPointFormula makeNumber( + Rational n, FloatingPointType type, FloatingPointRoundingMode pFloatingPointRoundingMode) { + throw new UnsupportedOperationException(); + } + + private String printSign(Sign pSign) { + return "FloatingPointNumber.Sign." + pSign.name(); + } + + @Override + public FloatingPointFormula makeNumber( + BigInteger exponent, BigInteger mantissa, Sign sign, FloatingPointType type) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "makeNumber(new BigInteger(\"%s\"), new BigInteger(\"%s\"), %s, %s)", + exponent, mantissa, printSign(sign), logger.printFormulaType(type)), + () -> delegate.makeNumber(exponent, mantissa, sign, type)); + } + + @Override + public FloatingPointFormula makeVariable(String pVar, FloatingPointType type) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("makeVariable(\"%s\", %s)", pVar, logger.printFormulaType(type)), + () -> delegate.makeVariable(pVar, type)); + } + + @Override + public FloatingPointFormula makePlusInfinity(FloatingPointType type) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("makePlusInfinity(%s)", logger.printFormulaType(type)), + () -> delegate.makePlusInfinity(type)); + } + + @Override + public FloatingPointFormula makeMinusInfinity(FloatingPointType type) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("makeMinusInfinity(%s)", logger.printFormulaType(type)), + () -> delegate.makeMinusInfinity(type)); + } + + @Override + public FloatingPointFormula makeNaN(FloatingPointType type) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("makeNaN(%s)", logger.printFormulaType(type)), + () -> delegate.makeNaN(type)); + } + + @Override + public T castTo( + FloatingPointFormula source, boolean signed, FormulaType targetType) { + return castTo(source, signed, targetType, FloatingPointRoundingMode.NEAREST_TIES_TO_EVEN); + } + + @Override + public T castTo( + FloatingPointFormula source, + boolean signed, + FormulaType targetType, + FloatingPointRoundingMode pFloatingPointRoundingMode) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "castTo(%s, %s, %s, %s)", + logger.toVariable(source), + signed, + logger.printFormulaType(targetType), + printRoundingMode(pFloatingPointRoundingMode)), + () -> delegate.castTo(source, signed, targetType, pFloatingPointRoundingMode)); + } + + @Override + public FloatingPointFormula castFrom( + Formula source, boolean signed, FloatingPointType targetType) { + return castFrom(source, signed, targetType, FloatingPointRoundingMode.NEAREST_TIES_TO_EVEN); + } + + @Override + public FloatingPointFormula castFrom( + Formula source, + boolean signed, + FloatingPointType targetType, + FloatingPointRoundingMode pFloatingPointRoundingMode) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "castFrom(%s, %s, %s, %s)", + logger.toVariable(source), + signed, + logger.printFormulaType(targetType), + printRoundingMode(pFloatingPointRoundingMode)), + () -> delegate.castFrom(source, signed, targetType, pFloatingPointRoundingMode)); + } + + @Override + public FloatingPointFormula fromIeeeBitvector( + BitvectorFormula number, FloatingPointType pTargetType) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "fromIeeeBitvector(%s, %s)", + logger.toVariable(number), logger.printFormulaType(pTargetType)), + () -> delegate.fromIeeeBitvector(number, pTargetType)); + } + + @Override + public BitvectorFormula toIeeeBitvector(FloatingPointFormula number) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("toIeeeBitvector(%s)", logger.toVariable(number)), + () -> delegate.toIeeeBitvector(number)); + } + + @Override + public FloatingPointFormula round( + FloatingPointFormula formula, FloatingPointRoundingMode roundingMode) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("round(%s, %s)", logger.toVariable(formula), printRoundingMode(roundingMode)), + () -> delegate.round(formula, roundingMode)); + } + + @Override + public FloatingPointFormula negate(FloatingPointFormula number) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("negate(%s)", logger.toVariable(number)), + () -> delegate.negate(number)); + } + + @Override + public FloatingPointFormula abs(FloatingPointFormula number) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("abs(%s)", logger.toVariable(number)), + () -> delegate.abs(number)); + } + + @Override + public FloatingPointFormula max(FloatingPointFormula number1, FloatingPointFormula number2) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("max(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.max(number1, number2)); + } + + @Override + public FloatingPointFormula min(FloatingPointFormula number1, FloatingPointFormula number2) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("min(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.min(number1, number2)); + } + + @Override + public FloatingPointFormula sqrt(FloatingPointFormula number) { + return sqrt(number, FloatingPointRoundingMode.NEAREST_TIES_TO_EVEN); + } + + @Override + public FloatingPointFormula sqrt( + FloatingPointFormula number, FloatingPointRoundingMode roundingMode) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("sqrt(%s, %s)", logger.toVariable(number), printRoundingMode(roundingMode)), + () -> delegate.sqrt(number, roundingMode)); + } + + @Override + public FloatingPointFormula add(FloatingPointFormula number1, FloatingPointFormula number2) { + return add(number1, number2, FloatingPointRoundingMode.NEAREST_TIES_TO_EVEN); + } + + @Override + public FloatingPointFormula add( + FloatingPointFormula number1, + FloatingPointFormula number2, + FloatingPointRoundingMode pFloatingPointRoundingMode) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "add(%s, %s, %s)", + logger.toVariable(number1), + logger.toVariable(number2), + printRoundingMode(pFloatingPointRoundingMode)), + () -> delegate.add(number1, number2, pFloatingPointRoundingMode)); + } + + @Override + public FloatingPointFormula subtract(FloatingPointFormula number1, FloatingPointFormula number2) { + return subtract(number1, number2, FloatingPointRoundingMode.NEAREST_TIES_TO_EVEN); + } + + @Override + public FloatingPointFormula subtract( + FloatingPointFormula number1, + FloatingPointFormula number2, + FloatingPointRoundingMode pFloatingPointRoundingMode) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "subtract(%s, %s, %s)", + logger.toVariable(number1), + logger.toVariable(number2), + printRoundingMode(pFloatingPointRoundingMode)), + () -> delegate.subtract(number1, number2, pFloatingPointRoundingMode)); + } + + @Override + public FloatingPointFormula divide(FloatingPointFormula number1, FloatingPointFormula number2) { + return divide(number1, number2, FloatingPointRoundingMode.NEAREST_TIES_TO_EVEN); + } + + @Override + public FloatingPointFormula divide( + FloatingPointFormula number1, + FloatingPointFormula number2, + FloatingPointRoundingMode pFloatingPointRoundingMode) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "divide(%s, %s, %s)", + logger.toVariable(number1), + logger.toVariable(number2), + printRoundingMode(pFloatingPointRoundingMode)), + () -> delegate.divide(number1, number2, pFloatingPointRoundingMode)); + } + + @Override + public FloatingPointFormula multiply(FloatingPointFormula number1, FloatingPointFormula number2) { + return multiply(number1, number2, FloatingPointRoundingMode.NEAREST_TIES_TO_EVEN); + } + + @Override + public FloatingPointFormula multiply( + FloatingPointFormula number1, + FloatingPointFormula number2, + FloatingPointRoundingMode pFloatingPointRoundingMode) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "multiply(%s, %s, %s)", + logger.toVariable(number1), + logger.toVariable(number2), + printRoundingMode(pFloatingPointRoundingMode)), + () -> delegate.multiply(number1, number2, pFloatingPointRoundingMode)); + } + + @Override + public FloatingPointFormula remainder( + FloatingPointFormula dividend, FloatingPointFormula divisor) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("remainder(%s, %s)", logger.toVariable(dividend), logger.toVariable(divisor)), + () -> delegate.remainder(dividend, divisor)); + } + + @Override + public BooleanFormula assignment(FloatingPointFormula number1, FloatingPointFormula number2) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("assignment(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.assignment(number1, number2)); + } + + @Override + public BooleanFormula equalWithFPSemantics( + FloatingPointFormula number1, FloatingPointFormula number2) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "equalWithFPSemantics(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.equalWithFPSemantics(number1, number2)); + } + + @Override + public BooleanFormula greaterThan(FloatingPointFormula number1, FloatingPointFormula number2) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "greaterThan(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.greaterThan(number1, number2)); + } + + @Override + public BooleanFormula greaterOrEquals( + FloatingPointFormula number1, FloatingPointFormula number2) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "greaterOrEquals(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.greaterOrEquals(number1, number2)); + } + + @Override + public BooleanFormula lessThan(FloatingPointFormula number1, FloatingPointFormula number2) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("lessThan(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.lessThan(number1, number2)); + } + + @Override + public BooleanFormula lessOrEquals(FloatingPointFormula number1, FloatingPointFormula number2) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format( + "lessOrEquals(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.lessOrEquals(number1, number2)); + } + + @Override + public BooleanFormula isNaN(FloatingPointFormula number) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("isNaN(%s)", logger.toVariable(number)), + () -> delegate.isNaN(number)); + } + + @Override + public BooleanFormula isInfinity(FloatingPointFormula number) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("isInfinity(%s)", logger.toVariable(number)), + () -> delegate.isInfinity(number)); + } + + @Override + public BooleanFormula isZero(FloatingPointFormula number) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("isZero(%s)", logger.toVariable(number)), + () -> delegate.isZero(number)); + } + + @Override + public BooleanFormula isNormal(FloatingPointFormula number) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("isNormal(%s)", logger.toVariable(number)), + () -> delegate.isNormal(number)); + } + + @Override + public BooleanFormula isSubnormal(FloatingPointFormula number) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("isSubnormal(%s)", logger.toVariable(number)), + () -> delegate.isSubnormal(number)); + } + + @Override + public BooleanFormula isNegative(FloatingPointFormula number) { + return logger.logDef( + "mgr.getFloatingPointFormulaManager()", + String.format("isNegative(%s)", logger.toVariable(number)), + () -> delegate.isNegative(number)); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceFormulaManager.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceFormulaManager.java new file mode 100644 index 0000000000..9649aa4cd2 --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceFormulaManager.java @@ -0,0 +1,259 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import java.util.List; +import java.util.Map; +import org.sosy_lab.common.Appender; +import org.sosy_lab.java_smt.api.ArrayFormulaManager; +import org.sosy_lab.java_smt.api.BitvectorFormulaManager; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.BooleanFormulaManager; +import org.sosy_lab.java_smt.api.EnumerationFormulaManager; +import org.sosy_lab.java_smt.api.FloatingPointFormulaManager; +import org.sosy_lab.java_smt.api.Formula; +import org.sosy_lab.java_smt.api.FormulaManager; +import org.sosy_lab.java_smt.api.FormulaType; +import org.sosy_lab.java_smt.api.FunctionDeclaration; +import org.sosy_lab.java_smt.api.IntegerFormulaManager; +import org.sosy_lab.java_smt.api.QuantifiedFormulaManager; +import org.sosy_lab.java_smt.api.QuantifiedFormulaManager.Quantifier; +import org.sosy_lab.java_smt.api.RationalFormulaManager; +import org.sosy_lab.java_smt.api.SLFormulaManager; +import org.sosy_lab.java_smt.api.SolverException; +import org.sosy_lab.java_smt.api.StringFormulaManager; +import org.sosy_lab.java_smt.api.Tactic; +import org.sosy_lab.java_smt.api.UFManager; +import org.sosy_lab.java_smt.api.visitors.FormulaTransformationVisitor; +import org.sosy_lab.java_smt.api.visitors.FormulaVisitor; +import org.sosy_lab.java_smt.api.visitors.TraversalProcess; + +public class TraceFormulaManager implements FormulaManager { + private final FormulaManager delegate; + private final TraceLogger logger; + + TraceFormulaManager(FormulaManager pDelegate, TraceLogger pLogger) { + delegate = pDelegate; + logger = pLogger; + } + + @Override + public IntegerFormulaManager getIntegerFormulaManager() { + return new TraceIntegerFormulaManager(delegate.getIntegerFormulaManager(), logger); + } + + @Override + public RationalFormulaManager getRationalFormulaManager() { + throw new UnsupportedOperationException(); + } + + @Override + public BooleanFormulaManager getBooleanFormulaManager() { + return new TraceBooleanFormulaManager(delegate.getBooleanFormulaManager(), logger); + } + + @Override + public ArrayFormulaManager getArrayFormulaManager() { + return new TraceArrayFormulaManager(delegate.getArrayFormulaManager(), logger); + } + + @Override + public BitvectorFormulaManager getBitvectorFormulaManager() { + return new TraceBitvectorFormulaManager(delegate.getBitvectorFormulaManager(), logger); + } + + @Override + public FloatingPointFormulaManager getFloatingPointFormulaManager() { + return new TraceFloatingPointFormulaManager(delegate.getFloatingPointFormulaManager(), logger); + } + + @Override + public UFManager getUFManager() { + return new TraceUFManager(delegate.getUFManager(), logger); + } + + @Override + public SLFormulaManager getSLFormulaManager() { + throw new UnsupportedOperationException(); + } + + @Override + public QuantifiedFormulaManager getQuantifiedFormulaManager() { + throw new UnsupportedOperationException(); + } + + @Override + public StringFormulaManager getStringFormulaManager() { + throw new UnsupportedOperationException(); + } + + @Override + public EnumerationFormulaManager getEnumerationFormulaManager() { + throw new UnsupportedOperationException(); + } + + @Override + public T makeVariable(FormulaType formulaType, String name) { + return logger.logDef( + "mgr", + String.format("makeVariable(%s, \"%s\")", logger.printFormulaType(formulaType), name), + () -> delegate.makeVariable(formulaType, name)); + } + + @Override + public T makeApplication( + FunctionDeclaration declaration, List args) { + throw new UnsupportedOperationException(); + } + + @Override + public T makeApplication( + FunctionDeclaration declaration, Formula... args) { + return makeApplication(declaration, ImmutableList.copyOf(args)); + } + + @Override + public FormulaType getFormulaType(T formula) { + // FIXME Add proper tracing + return delegate.getFormulaType(formula); + } + + @Override + public BooleanFormula parse(String s) throws IllegalArgumentException { + return logger.logDef("mgr", String.format("parse(\"%s\")", s), () -> delegate.parse(s)); + } + + @Override + public Appender dumpFormula(BooleanFormula pT) { + return logger.logDef( + "mgr", + String.format("dumpFormula(%s)", logger.toVariable(pT)), + () -> delegate.dumpFormula(pT)); + } + + @Override + public BooleanFormula applyTactic(BooleanFormula input, Tactic tactic) + throws InterruptedException, SolverException { + throw new UnsupportedOperationException(); + } + + @Override + public T simplify(T input) throws InterruptedException { + throw new UnsupportedOperationException(); + } + + private final class TraceVisitor implements FormulaVisitor { + private final FormulaVisitor delegateVisitor; + + private TraceVisitor(FormulaVisitor pDelegate) { + delegateVisitor = pDelegate; + } + + @Override + public T visitFreeVariable(Formula f, String name) { + return delegateVisitor.visitFreeVariable(f, name); + } + + @Override + public T visitConstant(Formula f, Object value) { + return delegateVisitor.visitConstant(f, value); + } + + @SuppressWarnings("unused") + @Override + public T visitFunction( + Formula f, List args, FunctionDeclaration functionDeclaration) { + for (int i = 0; i <= args.size(); i++) { + var value = i == 0 ? functionDeclaration : args.get(i - 1); + var unused = + logger.logDef( + "mgr", + String.format("visit(%s, new ExtractingVisitor(%s))", logger.toVariable(f), i), + () -> value); + } + return delegateVisitor.visitFunction(f, args, functionDeclaration); + } + + @SuppressWarnings("unused") + @Override + public T visitQuantifier( + BooleanFormula f, + Quantifier quantifier, + List boundVariables, + BooleanFormula body) { + for (int i = 0; i <= boundVariables.size(); i++) { + var value = i == boundVariables.size() ? body : boundVariables.get(i - 1); + var unused = + logger.logDef( + "mgr", + String.format("visit(%s, new ExtractingVisitor(%s))", logger.toVariable(f), i), + () -> value); + } + return delegateVisitor.visitQuantifier(f, quantifier, boundVariables, body); + } + } + + @Override + public R visit(Formula f, FormulaVisitor rFormulaVisitor) { + return delegate.visit(f, new TraceVisitor<>(rFormulaVisitor)); + } + + @Override + public void visitRecursively(Formula f, FormulaVisitor rFormulaVisitor) { + delegate.visitRecursively(f, new TraceVisitor<>(rFormulaVisitor)); + } + + @Override + public T transformRecursively( + T f, FormulaTransformationVisitor pFormulaVisitor) { + throw new UnsupportedOperationException(); + } + + @Override + public ImmutableMap extractVariables(Formula f) { + // FIXME Add proper tracing + return delegate.extractVariables(f); + } + + @Override + public ImmutableMap extractVariablesAndUFs(Formula f) { + throw new UnsupportedOperationException(); + } + + @Override + public T substitute( + T f, Map fromToMapping) { + throw new UnsupportedOperationException(); + } + + @Override + public BooleanFormula translateFrom(BooleanFormula formula, FormulaManager otherManager) { + // TODO Write API calls from all contexts into one file to allow us to support this method + throw new UnsupportedOperationException(); + } + + @Override + public boolean isValidName(String variableName) { + throw new UnsupportedOperationException(); + } + + @Override + public String escape(String variableName) { + throw new UnsupportedOperationException(); + } + + @Override + public String unescape(String variableName) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceIntegerFormulaManager.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceIntegerFormulaManager.java new file mode 100644 index 0000000000..338132499b --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceIntegerFormulaManager.java @@ -0,0 +1,198 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.List; +import org.sosy_lab.common.rationals.Rational; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.IntegerFormulaManager; +import org.sosy_lab.java_smt.api.NumeralFormula.IntegerFormula; + +public class TraceIntegerFormulaManager implements IntegerFormulaManager { + private final IntegerFormulaManager delegate; + private final TraceLogger logger; + + TraceIntegerFormulaManager(IntegerFormulaManager pDelegate, TraceLogger pLogger) { + delegate = pDelegate; + logger = pLogger; + } + + @Override + public BooleanFormula modularCongruence( + IntegerFormula number1, IntegerFormula number2, BigInteger n) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format( + "modularCongruence(%s, %s, new BigInteger(\"%s\"))", + logger.toVariable(number1), logger.toVariable(number2), n), + () -> delegate.modularCongruence(number1, number2, n)); + } + + @Override + public BooleanFormula modularCongruence(IntegerFormula number1, IntegerFormula number2, long n) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format( + "modularCongruence(%s, %s, %s)", + logger.toVariable(number1), logger.toVariable(number2), n), + () -> delegate.modularCongruence(number1, number2, n)); + } + + @Override + public IntegerFormula modulo(IntegerFormula numerator, IntegerFormula denominator) { + throw new UnsupportedOperationException(); + } + + @Override + public IntegerFormula makeNumber(long number) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format("makeNumber(%s)", number), + () -> delegate.makeNumber(number)); + } + + @Override + public IntegerFormula makeNumber(BigInteger number) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format("makeNumber(new BigInteger(\"%s\"))", number), + () -> delegate.makeNumber(number)); + } + + @Override + public IntegerFormula makeNumber(double number) { + throw new UnsupportedOperationException(); + } + + @Override + public IntegerFormula makeNumber(BigDecimal number) { + throw new UnsupportedOperationException(); + } + + @Override + public IntegerFormula makeNumber(String pI) { + throw new UnsupportedOperationException(); + } + + @Override + public IntegerFormula makeNumber(Rational pRational) { + throw new UnsupportedOperationException(); + } + + @Override + public IntegerFormula makeVariable(String pVar) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format("makeVariable(\"%s\")", pVar), + () -> delegate.makeVariable(pVar)); + } + + @Override + public IntegerFormula negate(IntegerFormula number) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format("negate(%s)", logger.toVariable(number)), + () -> delegate.negate(number)); + } + + @Override + public IntegerFormula add(IntegerFormula number1, IntegerFormula number2) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format("add(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.add(number1, number2)); + } + + @Override + public IntegerFormula sum(List operands) { + throw new UnsupportedOperationException(); + } + + @Override + public IntegerFormula subtract(IntegerFormula number1, IntegerFormula number2) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format("subtract(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.subtract(number1, number2)); + } + + @Override + public IntegerFormula divide(IntegerFormula numerator, IntegerFormula denominator) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format( + "divide(%s, %s)", logger.toVariable(numerator), logger.toVariable(denominator)), + () -> delegate.divide(numerator, denominator)); + } + + @Override + public IntegerFormula multiply(IntegerFormula number1, IntegerFormula number2) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format("multiply(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.multiply(number1, number2)); + } + + @Override + public BooleanFormula equal(IntegerFormula number1, IntegerFormula number2) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format("equal(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.equal(number1, number2)); + } + + @Override + public BooleanFormula distinct(List pNumbers) { + throw new UnsupportedOperationException(); + } + + @Override + public BooleanFormula greaterThan(IntegerFormula number1, IntegerFormula number2) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format( + "greaterThan(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.greaterThan(number1, number2)); + } + + @Override + public BooleanFormula greaterOrEquals(IntegerFormula number1, IntegerFormula number2) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format( + "greaterOrEquals(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.greaterOrEquals(number1, number2)); + } + + @Override + public BooleanFormula lessThan(IntegerFormula number1, IntegerFormula number2) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format("lessThan(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.lessThan(number1, number2)); + } + + @Override + public BooleanFormula lessOrEquals(IntegerFormula number1, IntegerFormula number2) { + return logger.logDef( + "mgr.getIntegerFormulaManager()", + String.format( + "lessOrEquals(%s, %s)", logger.toVariable(number1), logger.toVariable(number2)), + () -> delegate.lessOrEquals(number1, number2)); + } + + @Override + public IntegerFormula floor(IntegerFormula formula) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceLogger.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceLogger.java new file mode 100644 index 0000000000..c60317ca6d --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceLogger.java @@ -0,0 +1,150 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import com.google.common.base.Preconditions; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Callable; +import org.sosy_lab.java_smt.api.Formula; +import org.sosy_lab.java_smt.api.FormulaType; +import org.sosy_lab.java_smt.api.FormulaType.ArrayFormulaType; +import org.sosy_lab.java_smt.api.FormulaType.BitvectorType; +import org.sosy_lab.java_smt.api.FormulaType.FloatingPointType; + +class TraceLogger { + private long id = 0; + + private final Map valueMap = new HashMap<>(); + private final BufferedWriter output; + + TraceLogger(String pFile) { + // FIXME Check if the file already exists + try { + output = Files.newBufferedWriter(Path.of(pFile), Charset.defaultCharset()); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + /** Returns a fresh variable. */ + private String newVariable() { + return "var" + id++; + } + + /** + * Bind an object to a variable. + * + *

Use {@link #toVariable(Object)} to get the variable name for a tracked object + */ + private void mapVariable(String pVar, Object f) { + valueMap.putIfAbsent(f, pVar); + } + + /** + * Returns the variable name of a tracked object. + * + *

Use {@link #mapVariable(String, Object)} to bind an object to a variable + */ + public String toVariable(Object f) { + String r = valueMap.get(f); + Preconditions.checkArgument(r != null, "Object not tracked"); + return r; + } + + /** Add a definition to the log. */ + public void appendDef(String pVar, String pExpr) { + try { + output.append(String.format("var %s = %s;%n", pVar, pExpr)); + output.flush(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** Add a statement to the log. */ + public void appendStmt(String pStmt) { + try { + output.append(String.format("%s;%n", pStmt)); + output.flush(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** Log an API call with return value. */ + public R logDef(String prefix, String method, Callable closure) { + String var = newVariable(); + try { + appendDef(var, prefix + "." + method); + R f = closure.call(); + mapVariable(var, f); + return f; + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** Just like {@link Runnable}, but allows checked exceptions. */ + public interface CheckedRunnable { + void run() throws Exception; + } + + /** Log an API call without return value. */ + public void logStmt(String prefix, String method, CheckedRunnable closure) { + try { + appendStmt(prefix + "." + method); + closure.run(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Takes a {@link org.sosy_lab.java_smt.api.FormulaType} and returns a Java expression to + * construct this type. + */ + public String printFormulaType(FormulaType pType) { + if (pType.isBooleanType()) { + return "FormulaType.BooleanType"; + } + if (pType.isIntegerType()) { + return "FormulaType.IntegerType"; + } + if (pType.isRationalType()) { + return "FormulaType.RationalType"; + } + if (pType.isArrayType()) { + ArrayFormulaType arrayType = (ArrayFormulaType) pType; + return String.format( + "FormulaType.getArrayType(%s, %s)", + printFormulaType(arrayType.getIndexType()), printFormulaType(arrayType.getElementType())); + } + if (pType.isBitvectorType()) { + BitvectorType bvType = (BitvectorType) pType; + return String.format("FormulaType.getBitvectorTypeWithSize(%s)", bvType.getSize()); + } + if (pType.isFloatingPointType()) { + FloatingPointType fpType = (FloatingPointType) pType; + return String.format( + "FormulaType.getFloatingPointType(%s, %s)", + fpType.getExponentSize(), fpType.getMantissaSize()); + } + // FIXME Handle other cases + throw new IllegalArgumentException("Unsupported formula type: " + pType); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceModel.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceModel.java new file mode 100644 index 0000000000..6b6cc1e123 --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceModel.java @@ -0,0 +1,120 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import com.google.common.collect.ImmutableList; +import java.math.BigInteger; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.rationals.Rational; +import org.sosy_lab.java_smt.api.BitvectorFormula; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.EnumerationFormula; +import org.sosy_lab.java_smt.api.FloatingPointFormula; +import org.sosy_lab.java_smt.api.FloatingPointNumber; +import org.sosy_lab.java_smt.api.Formula; +import org.sosy_lab.java_smt.api.Model; +import org.sosy_lab.java_smt.api.NumeralFormula.IntegerFormula; +import org.sosy_lab.java_smt.api.NumeralFormula.RationalFormula; +import org.sosy_lab.java_smt.api.StringFormula; + +public class TraceModel implements Model { + private final Model delegate; + private final TraceLogger logger; + + TraceModel(Model pDelegate, TraceLogger pLogger) { + delegate = pDelegate; + logger = pLogger; + } + + @Override + public ImmutableList asList() { + // FIXME We need to introduce local variables for all terms in the model so that they can be + // referenced later + return logger.logDef(logger.toVariable(this), "asList()", delegate::asList); + } + + @Override + public @Nullable T eval(T formula) { + return logger.logDef( + logger.toVariable(this), + String.format("eval(%s)", logger.toVariable(formula)), + () -> delegate.eval(formula)); + } + + @Override + public @Nullable Object evaluate(Formula formula) { + return logger.logDef( + logger.toVariable(this), + String.format("evaluate(%s)", logger.toVariable(formula)), + () -> delegate.evaluate(formula)); + } + + @Override + public @Nullable BigInteger evaluate(IntegerFormula formula) { + return logger.logDef( + logger.toVariable(this), + String.format("evaluate(%s)", logger.toVariable(formula)), + () -> delegate.evaluate(formula)); + } + + @Override + public @Nullable Rational evaluate(RationalFormula formula) { + return logger.logDef( + logger.toVariable(this), + String.format("evaluate(%s)", logger.toVariable(formula)), + () -> delegate.evaluate(formula)); + } + + @Override + public @Nullable Boolean evaluate(BooleanFormula formula) { + return logger.logDef( + logger.toVariable(this), + String.format("evaluate(%s)", logger.toVariable(formula)), + () -> delegate.evaluate(formula)); + } + + @Override + public @Nullable BigInteger evaluate(BitvectorFormula formula) { + return logger.logDef( + logger.toVariable(this), + String.format("evaluate(%s)", logger.toVariable(formula)), + () -> delegate.evaluate(formula)); + } + + @Override + public @Nullable String evaluate(StringFormula formula) { + return logger.logDef( + logger.toVariable(this), + String.format("evaluate(%s)", logger.toVariable(formula)), + () -> delegate.evaluate(formula)); + } + + @Override + public @Nullable String evaluate(EnumerationFormula formula) { + return logger.logDef( + logger.toVariable(this), + String.format("evaluate(%s)", logger.toVariable(formula)), + () -> delegate.evaluate(formula)); + } + + @Override + public @Nullable FloatingPointNumber evaluate(FloatingPointFormula formula) { + return logger.logDef( + logger.toVariable(this), + String.format("evaluate(%s)", logger.toVariable(formula)), + () -> delegate.evaluate(formula)); + } + + @Override + public void close() { + logger.logStmt(logger.toVariable(this), "close()", delegate::close); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceProverEnvironment.java new file mode 100644 index 0000000000..d8c1e79ef6 --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceProverEnvironment.java @@ -0,0 +1,21 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import org.sosy_lab.java_smt.api.BasicProverEnvironment; +import org.sosy_lab.java_smt.api.ProverEnvironment; + +public class TraceProverEnvironment extends TraceBasicProverEnvironment + implements ProverEnvironment { + TraceProverEnvironment(BasicProverEnvironment pDelegate, TraceLogger pLogger) { + super(pDelegate, pLogger); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceSolverContext.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceSolverContext.java new file mode 100644 index 0000000000..ffbd4a7e8e --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceSolverContext.java @@ -0,0 +1,116 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableMap; +import java.util.List; +import java.util.Map.Entry; +import org.sosy_lab.common.configuration.Configuration; +import org.sosy_lab.java_smt.SolverContextFactory.Solvers; +import org.sosy_lab.java_smt.api.FormulaManager; +import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; +import org.sosy_lab.java_smt.api.OptimizationProverEnvironment; +import org.sosy_lab.java_smt.api.ProverEnvironment; +import org.sosy_lab.java_smt.api.SolverContext; + +public class TraceSolverContext implements SolverContext { + private final SolverContext delegate; + private final TraceLogger logger; + + public TraceSolverContext(Solvers pSolver, Configuration config, SolverContext pDelegate) { + delegate = pDelegate; + // FIXME Move the files to the output folder? + logger = + new TraceLogger( + "trace" + Integer.toUnsignedString(System.identityHashCode(this)) + ".java"); + + // Get relevant options from the configuration + String props = config.asPropertiesString(); + ImmutableMap.Builder options = ImmutableMap.builder(); + for (String s : props.lines().toArray(String[]::new)) { + List parts = Splitter.on(" = ").splitToList(s); + if (parts.get(0).startsWith("solver") + && !parts.get(0).equals("solver.trace") + && !parts.get(0).equals("solver.solver")) { + options.put(parts.get(0), parts.get(1)); + } + } + + // Write code for creating a solver context to the trace log + logger.appendDef( + "config", + "Configuration.builder()." + + FluentIterable.from(options.buildOrThrow().entrySet()) + .transform( + (Entry e) -> + String.format("setOption(\"%s\", \"%s\")", e.getKey(), e.getValue())) + .join(Joiner.on(".")) + + ".build()"); + logger.appendDef("logger", "LogManager.createNullLogManager()"); + logger.appendDef("notifier", "ShutdownNotifier.createDummy()"); + logger.appendDef( + "context", + "SolverContextFactory.createSolverContext(config, logger, notifier, " + + "SolverContextFactory.Solvers." + + pSolver.name() + + ")"); + logger.appendDef("mgr", "context.getFormulaManager()"); + } + + @Override + public FormulaManager getFormulaManager() { + return new TraceFormulaManager(delegate.getFormulaManager(), logger); + } + + @SuppressWarnings("resource") + @Override + public ProverEnvironment newProverEnvironment(ProverOptions... options) { + return logger.logDef( + "context", + String.format( + "newProverEnvironment(%s)", + FluentIterable.from(options) + .transform(v -> "SolverContext" + ".ProverOptions." + v.name()) + .join(Joiner.on(", "))), + () -> new TraceProverEnvironment(delegate.newProverEnvironment(options), logger)); + } + + @SuppressWarnings("resource") + @Override + public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( + ProverOptions... options) { + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("resource") + @Override + public OptimizationProverEnvironment newOptimizationProverEnvironment(ProverOptions... options) { + throw new UnsupportedOperationException(); + } + + @Override + public String getVersion() { + return delegate.getVersion(); + } + + @Override + public Solvers getSolverName() { + return delegate.getSolverName(); + } + + @Override + public void close() { + logger.logStmt("context", "close()", delegate::close); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/TraceUFManager.java b/src/org/sosy_lab/java_smt/delegate/trace/TraceUFManager.java new file mode 100644 index 0000000000..a01af0a494 --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/TraceUFManager.java @@ -0,0 +1,78 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.delegate.trace; + +import com.google.common.base.Joiner; +import com.google.common.collect.FluentIterable; +import java.util.Arrays; +import java.util.List; +import org.sosy_lab.java_smt.api.Formula; +import org.sosy_lab.java_smt.api.FormulaType; +import org.sosy_lab.java_smt.api.FunctionDeclaration; +import org.sosy_lab.java_smt.api.UFManager; + +public class TraceUFManager implements UFManager { + private final UFManager delegate; + private final TraceLogger logger; + + TraceUFManager(UFManager pDelegate, TraceLogger pLogger) { + delegate = pDelegate; + logger = pLogger; + } + + @Override + public FunctionDeclaration declareUF( + String name, FormulaType returnType, List> args) { + return logger.logDef( + "mgr.getUFManager()", + String.format( + "declareUF(\"%s\", %s, ImmutableList.of(%s))", + name, + logger.printFormulaType(returnType), + FluentIterable.from(args).transform(logger::printFormulaType).join(Joiner.on(", "))), + () -> delegate.declareUF(name, returnType, args)); + } + + @Override + public FunctionDeclaration declareUF( + String name, FormulaType returnType, FormulaType... args) { + return declareUF(name, returnType, Arrays.asList(args)); + } + + @Override + public T callUF( + FunctionDeclaration funcType, List args) { + return logger.logDef( + "mgr.getUFManager()", + String.format( + "callUF(%s, ImmutableList.of(%s))", + logger.toVariable(funcType), + FluentIterable.from(args).transform(logger::toVariable).join(Joiner.on(", "))), + () -> delegate.callUF(funcType, args)); + } + + @Override + public T callUF(FunctionDeclaration funcType, Formula... args) { + return callUF(funcType, Arrays.asList(args)); + } + + @Override + public T declareAndCallUF( + String name, FormulaType pReturnType, List pArgs) { + throw new UnsupportedOperationException(); + } + + @Override + public T declareAndCallUF( + String name, FormulaType pReturnType, Formula... pArgs) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/trace/package-info.java b/src/org/sosy_lab/java_smt/delegate/trace/package-info.java new file mode 100644 index 0000000000..1b69a33f5b --- /dev/null +++ b/src/org/sosy_lab/java_smt/delegate/trace/package-info.java @@ -0,0 +1,15 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2025 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +@com.google.errorprone.annotations.CheckReturnValue +@javax.annotation.ParametersAreNonnullByDefault +@org.sosy_lab.common.annotations.FieldsAreNonnullByDefault +@org.sosy_lab.common.annotations.ReturnValuesAreNonnullByDefault +package org.sosy_lab.java_smt.delegate.trace;