diff --git a/buildSrc/src/main/kotlin/Properties.kt b/buildSrc/src/main/kotlin/Properties.kt index 802364914..24d60d85e 100644 --- a/buildSrc/src/main/kotlin/Properties.kt +++ b/buildSrc/src/main/kotlin/Properties.kt @@ -1,7 +1,9 @@ import org.gradle.api.Project fun Project.booleanProperty(name: String): Boolean? { - if (!project.hasProperty(name)) return null - val value = project.property(name) - return value?.toString()?.toBoolean() + if (!project.hasProperty(name)) { + return null + } + + return project.property(name)?.toString()?.toBoolean() } diff --git a/buildSrc/src/main/kotlin/Publications.kt b/buildSrc/src/main/kotlin/Publications.kt index 81242a5a2..4860c1cd9 100644 --- a/buildSrc/src/main/kotlin/Publications.kt +++ b/buildSrc/src/main/kotlin/Publications.kt @@ -4,11 +4,12 @@ import org.gradle.api.component.SoftwareComponent import org.gradle.kotlin.dsl.get fun Project.removeTestFixtures(softwareComponent: SoftwareComponent) { - val componenet = softwareComponent as AdhocComponentWithVariants - componenet.withVariantsFromConfiguration(configurations["testFixturesApiElements"]) { - skip() - } - componenet.withVariantsFromConfiguration(configurations["testFixturesRuntimeElements"]) { - skip() + with(softwareComponent as AdhocComponentWithVariants) { + withVariantsFromConfiguration(configurations["testFixturesApiElements"]) { + skip() + } + withVariantsFromConfiguration(configurations["testFixturesRuntimeElements"]) { + skip() + } } } diff --git a/buildSrc/src/main/kotlin/SmtLibBenchmarkUtil.kt b/buildSrc/src/main/kotlin/SmtLibBenchmarkUtil.kt index e76db65a0..5e73be770 100644 --- a/buildSrc/src/main/kotlin/SmtLibBenchmarkUtil.kt +++ b/buildSrc/src/main/kotlin/SmtLibBenchmarkUtil.kt @@ -9,11 +9,12 @@ fun Project.mkSmtLibBenchmarkTestData(name: String) = tasks.register("smtLibBenc doLast { val path = buildDir.resolve("smtLibBenchmark/$name") val downloadTarget = path.resolve("$name.zip") - val repoUrl = "https://clc-gitlab.cs.uiowa.edu:2443" - val url = "$repoUrl/api/v4/projects/SMT-LIB-benchmarks%2F$name/repository/archive.zip" + val url = "$BENCHMARK_REPO_URL/api/v4/projects/SMT-LIB-benchmarks%2F$name/repository/archive.zip" + download(url, downloadTarget) val unpackCompleteMarker = path.resolve("unpack-complete") + if (!unpackCompleteMarker.exists()) { copy { from(zipTree(downloadTarget)) @@ -23,10 +24,10 @@ fun Project.mkSmtLibBenchmarkTestData(name: String) = tasks.register("smtLibBenc unpackCompleteMarker.createNewFile() } - val testResources = testResourceDir()!! + val testResources = testResourceDir() ?: error("No resource directory found for $name benchmark") val testData = testResources.resolve("testData") - val testDataCopyCompleteMarker = testData.resolve("$name-copy-complete") + if (!testDataCopyCompleteMarker.exists()) { val smtFiles = path.walkTopDown().filter { it.extension == "smt2" }.toList() copy { @@ -42,5 +43,7 @@ fun Project.mkSmtLibBenchmarkTestData(name: String) = tasks.register("smtLibBenc private fun Project.testResourceDir(): File? { val sourceSets = (this as ExtensionAware).extensions.getByName("sourceSets") as SourceSetContainer - return sourceSets["test"].output.resourcesDir + return sourceSets["test"]?.output?.resourcesDir } + +private const val BENCHMARK_REPO_URL = "https://clc-gitlab.cs.uiowa.edu:2443" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927a4..249e5832f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aa991fcea..ae04661ee 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c78733..a69d9cb6c 100755 --- a/gradlew +++ b/gradlew @@ -205,6 +205,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd32c..f127cfd49 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaContext.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaContext.kt index 70882dfd9..3eb8f3121 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaContext.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaContext.kt @@ -9,13 +9,14 @@ import org.ksmt.solver.bitwuzla.bindings.BitwuzlaSort import org.ksmt.solver.bitwuzla.bindings.BitwuzlaTerm import org.ksmt.solver.bitwuzla.bindings.Native import org.ksmt.sort.KSort +import java.util.Collections import kotlin.time.Duration import kotlin.time.ExperimentalTime import kotlin.time.TimeMark import kotlin.time.TimeSource open class KBitwuzlaContext : AutoCloseable { - private var closed = false + private var isClosed = false val bitwuzla = Native.bitwuzlaNew() @@ -39,11 +40,11 @@ open class KBitwuzlaContext : AutoCloseable { * internalization of already internalized expressions. * * [internalizer] must use special functions to internalize BitVec values ([internalizeBvValue]) - * and constants ([mkConstant]) + * and constants ([mkConstant]). * */ fun internalizeExpr(expr: KExpr<*>, internalizer: (KExpr<*>) -> BitwuzlaTerm): BitwuzlaTerm = expressions.getOrPut(expr) { - internalizer(expr) // don't reverse cache bitwuzla term since it may be rewrited + internalizer(expr) // don't reverse cache bitwuzla term since it may be rewrote } fun internalizeSort(sort: KSort, internalizer: (KSort) -> BitwuzlaSort): BitwuzlaSort = @@ -58,7 +59,8 @@ open class KBitwuzlaContext : AutoCloseable { internalizer(decl) } - /** Internalize and reverse cache Bv value to support Bv values conversion. + /** + * Internalize and reverse cache Bv value to support Bv values conversion. * * Since [Native.bitwuzlaGetBvValue] is only available after check-sat call * we must reverse cache Bv values to be able to convert all previously internalized @@ -78,41 +80,45 @@ open class KBitwuzlaContext : AutoCloseable { fun convertValue(value: BitwuzlaTerm): KExpr<*>? = bvValues[value] - // constant is known only if it was previously internalized + // Constant is known only if it was previously internalized fun convertConstantIfKnown(term: BitwuzlaTerm): KDecl<*>? = bitwuzlaConstants[term] private val normalConstantScope: NormalConstantScope = NormalConstantScope() var currentConstantScope: ConstantScope = normalConstantScope - fun declaredConstants(): Set> = normalConstantScope.constants.toSet() + fun declaredConstants(): Set> = Collections.unmodifiableSet(normalConstantScope.constants) - /** Internalize constant. + /** + * Internalize constant. * 1. Since [Native.bitwuzlaMkConst] creates fresh constant on each invocation caches are used - * to guarantee that if two constants are equal in ksmt they are also equal in Bitwuzla - * 2. Scoping is used to support quantifier bound variables (see [withConstantScope]) + * to guarantee that if two constants are equal in ksmt they are also equal in Bitwuzla; + * 2. Scoping is used to support quantifier bound variables (see [withConstantScope]). * */ fun mkConstant(decl: KDecl<*>, sort: BitwuzlaSort): BitwuzlaTerm = currentConstantScope.mkConstant(decl, sort) - /** Constant scope for quantifiers. + /** + * Constant scope for quantifiers. * * Quantifier bound variables: - * 1. may clash with constants from outer scope - * 2. must be replaced with vars in quantifier body + * 1. may clash with constants from outer scope; + * 2. must be replaced with vars in quantifier body. * * @see QuantifiedConstantScope * */ inline fun withConstantScope(body: QuantifiedConstantScope.() -> T): T { val oldScope = currentConstantScope val newScope = QuantifiedConstantScope(currentConstantScope) + currentConstantScope = newScope val result = newScope.body() currentConstantScope = oldScope + return result } /** - * keep strong reference to bitwuzla timeout callback to avoid sigsegv + * Keep strong reference to bitwuzla timeout callback to avoid sigsegv. * */ private var timeoutTerminator: BitwuzlaTimeout? = null @@ -122,9 +128,11 @@ open class KBitwuzlaContext : AutoCloseable { Native.bitwuzlaResetTerminationCallback(bitwuzla) return body() } + val currentTime = TimeSource.Monotonic.markNow() val finishTime = currentTime + timeout timeoutTerminator = BitwuzlaTimeout(finishTime) + try { Native.bitwuzlaSetTerminationCallback(bitwuzla, timeoutTerminator, state = null) return body() @@ -142,7 +150,7 @@ open class KBitwuzlaContext : AutoCloseable { } override fun close() { - closed = true + isClosed = true sorts.clear() bitwuzlaSorts.clear() expressions.clear() @@ -153,7 +161,7 @@ open class KBitwuzlaContext : AutoCloseable { } fun ensureActive() { - check(!closed) { "context already closed" } + check(!isClosed) { "The context is already closed." } } private inline fun convert( @@ -169,6 +177,7 @@ open class KBitwuzlaContext : AutoCloseable { val converted = converter(key) cache.putIfAbsent(converted, key) reverseCache[key] = converted + return converted } @@ -177,10 +186,11 @@ open class KBitwuzlaContext : AutoCloseable { } - /** Produce normal constants for KSmt declarations. + /** + * Produce normal constants for KSMT declarations. * - * Guarantee that if two declarations are equal - * then same Bitwuzla native pointer is returned. + * Guarantee that if two declarations are equal + * then the same Bitwuzla native pointer is returned. * */ inner class NormalConstantScope : ConstantScope { val constants = hashSetOf>() @@ -194,16 +204,18 @@ open class KBitwuzlaContext : AutoCloseable { override fun mkConstant(decl: KDecl<*>, sort: BitwuzlaSort): BitwuzlaTerm = constantCache.create(decl, sort) } - /** Constant quantification. + /** + * Constant quantification. * - * If constant declaration registered as quantified variable, + * If constant declaration is registered as quantified variable, * then the corresponding var is returned instead of constant. * */ inner class QuantifiedConstantScope(private val parent: ConstantScope) : ConstantScope { private val constants = hashMapOf, BitwuzlaSort>, BitwuzlaTerm>() - fun mkVar(decl: KDecl<*>, sort: BitwuzlaSort): BitwuzlaTerm = constants.getOrPut(decl to sort) { - Native.bitwuzlaMkVar(bitwuzla, sort, decl.name) - } + fun mkVar(decl: KDecl<*>, sort: BitwuzlaSort): BitwuzlaTerm = + constants.getOrPut(decl to sort) { + Native.bitwuzlaMkVar(bitwuzla, sort, decl.name) + } override fun mkConstant(decl: KDecl<*>, sort: BitwuzlaSort): BitwuzlaTerm = constants[decl to sort] ?: parent.mkConstant(decl, sort) @@ -213,5 +225,4 @@ open class KBitwuzlaContext : AutoCloseable { class BitwuzlaTimeout(private val finishTime: TimeMark) : Native.BitwuzlaTerminationCallback { override fun terminate(state: Pointer?): Int = if (finishTime.hasNotPassedNow()) 0 else 1 } - } diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaExprConverter.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaExprConverter.kt index 50b54c3f7..d723c0f23 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaExprConverter.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaExprConverter.kt @@ -6,7 +6,7 @@ import org.ksmt.decl.KFuncDecl import org.ksmt.expr.KBitVecValue import org.ksmt.expr.KExpr import org.ksmt.expr.transformer.KNonRecursiveTransformer -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.solver.bitwuzla.bindings.BitwuzlaKind import org.ksmt.solver.bitwuzla.bindings.BitwuzlaSort import org.ksmt.solver.bitwuzla.bindings.BitwuzlaTerm @@ -24,20 +24,22 @@ open class KBitwuzlaExprConverter( ) : KExprConverterBase() { private val adapterTermRewriter = AdapterTermRewriter(ctx) - private val incompleteDeclarations = mutableSetOf>() + private val incompleteDeclarations = hashSetOf>() - /** New declarations introduced by Bitwuzla to return correct expressions. + /** + * New declarations introduced by Bitwuzla to return correct expressions. * - * For example, when converting array with partial interpretation, - * default value will be represented with new unnamed declaration. + * For example, when converting array with partial interpretation, + * default value will be represented with new unnamed declaration. * - * @see generateDecl + * @see generateDecl * */ val incompleteDecls: Set> get() = incompleteDeclarations /** - * Create KSmt expression from Bitwuzla term. + * Create KSMT expression from Bitwuzla term. + * * @param expectedSort expected sort of resulting expression * * @see convertToExpectedIfNeeded @@ -71,13 +73,13 @@ open class KBitwuzlaExprConverter( mkArraySort(domain, range) } Native.bitwuzlaSortIsFun(sort) -> { - error("fun sorts are not allowed for conversion") + error("Fun sorts are not allowed for conversion") } Native.bitwuzlaSortIsBv(sort) -> { val size = Native.bitwuzlaSortBvGetSize(sort) mkBvSort(size.toUInt()) } - else -> TODO("sort is not supported") + else -> TODO("Given sort $sort is not supported yet") } } @@ -212,15 +214,20 @@ open class KBitwuzlaExprConverter( private fun KContext.convertFunctionApp(expr: BitwuzlaTerm): ExprConversionResult { val children = Native.bitwuzlaTermGetChildren(expr) + check(children.isNotEmpty()) { "Apply has no function term" } + val function = children[0] val appArgs = children.drop(1).toTypedArray() + return expr.convertList(appArgs) { convertedArgs: List> -> - check(Native.bitwuzlaTermIsFun(function)) { "function term expected" } + check(Native.bitwuzlaTermIsFun(function)) { "Expected a function term, actual: $function" } + val funcDecl = convertFuncDecl(function) val args = convertedArgs.zip(funcDecl.argSorts) { arg, expectedSort -> arg.convertToExpectedIfNeeded(expectedSort) } + funcDecl.apply(args).convertToBoolIfNeeded() } } @@ -229,18 +236,19 @@ open class KBitwuzlaExprConverter( val knownFuncDecl = bitwuzlaCtx.convertConstantIfKnown(function) if (knownFuncDecl != null) { - return knownFuncDecl as? KFuncDecl<*> - ?: error("function expected. actual: $knownFuncDecl") + return knownFuncDecl as? KFuncDecl<*> ?: error("Expected a function, actual: $knownFuncDecl") } // new function val domain = Native.bitwuzlaTermFunGetDomainSorts(function).map { it.convertSort() } val range = Native.bitwuzlaTermFunGetCodomainSort(function).convertSort() + return generateDecl(function) { mkFuncDecl(it, range, domain) } } - private fun KContext.convertConst(expr: BitwuzlaTerm): ExprConversionResult = convert { + private fun KContext.convertConst(expr: BitwuzlaTerm): ExprConversionResult = convert { val knownConstDecl = bitwuzlaCtx.convertConstantIfKnown(expr) + if (knownConstDecl != null) { @Suppress("UNCHECKED_CAST") return@convert mkConstApp(knownConstDecl).convertToBoolIfNeeded() as KExpr @@ -248,6 +256,7 @@ open class KBitwuzlaExprConverter( // newly generated constant val sort = Native.bitwuzlaTermGetSort(expr) + if (!Native.bitwuzlaSortIsFun(sort) || Native.bitwuzlaSortIsArray(sort)) { val decl = generateDecl(expr) { mkConstDecl(it, sort.convertSort()) } @Suppress("UNCHECKED_CAST") @@ -270,18 +279,19 @@ open class KBitwuzlaExprConverter( convertBvValue(expr) } Native.bitwuzlaTermIsFp(expr) -> TODO("FP are not supported yet") - else -> TODO("unsupported value") + else -> TODO("unsupported value $expr") } } private fun KContext.convertBvValue(expr: BitwuzlaTerm): KBitVecValue { val size = Native.bitwuzlaTermBvGetSize(expr) + val convertedValue = if (Native.bitwuzlaTermIsBvValue(expr)) { // convert Bv value from native representation val nativeBits = Native.bitwuzlaBvConstNodeGetBits(expr) val nativeBitsSize = Native.bitwuzlaBvBitsGetWidth(nativeBits) - check(size == nativeBitsSize) { "bv size mismatch" } + check(size == nativeBitsSize) { "Bv size mismatch, expr size $size, native size $nativeBitsSize " } val bits = if (size <= Long.SIZE_BITS) { val numericValue = Native.bitwuzlaBvBitsToUInt64(nativeBits).toULong() @@ -335,7 +345,7 @@ open class KBitwuzlaExprConverter( BitwuzlaKind.BITWUZLA_KIND_BV_XOR -> expr.convertBv(::mkBvXorExpr) BitwuzlaKind.BITWUZLA_KIND_BV_REDAND -> expr.convertBv(::mkBvReductionAndExpr) BitwuzlaKind.BITWUZLA_KIND_BV_REDOR -> expr.convertBv(::mkBvReductionOrExpr) - BitwuzlaKind.BITWUZLA_KIND_BV_REDXOR -> TODO("$kind") + BitwuzlaKind.BITWUZLA_KIND_BV_REDXOR -> TODO("$kind conversion is unsupported yet") BitwuzlaKind.BITWUZLA_KIND_BV_SGE -> expr.convertBv(::mkBvSignedGreaterOrEqualExpr) BitwuzlaKind.BITWUZLA_KIND_BV_SGT -> expr.convertBv(::mkBvSignedGreaterExpr) BitwuzlaKind.BITWUZLA_KIND_BV_SLE -> expr.convertBv(::mkBvSignedLessOrEqualExpr) @@ -347,7 +357,7 @@ open class KBitwuzlaExprConverter( BitwuzlaKind.BITWUZLA_KIND_BV_ADD -> expr.convertBv(::mkBvAddExpr) BitwuzlaKind.BITWUZLA_KIND_BV_SUB -> expr.convertBv(::mkBvSubExpr) BitwuzlaKind.BITWUZLA_KIND_BV_DEC, - BitwuzlaKind.BITWUZLA_KIND_BV_INC -> TODO("$kind") + BitwuzlaKind.BITWUZLA_KIND_BV_INC -> TODO("$kind conversion is unsupported yet") BitwuzlaKind.BITWUZLA_KIND_BV_MUL -> expr.convertBv(::mkBvMulExpr) BitwuzlaKind.BITWUZLA_KIND_BV_SDIV -> expr.convertBv(::mkBvSignedDivExpr) BitwuzlaKind.BITWUZLA_KIND_BV_SMOD -> expr.convertBv(::mkBvSignedModExpr) @@ -419,6 +429,7 @@ open class KBitwuzlaExprConverter( val declName = name ?: generateBitwuzlaSymbol(term) val decl = generator(declName) incompleteDeclarations += decl + return decl } @@ -430,7 +441,8 @@ open class KBitwuzlaExprConverter( return "uf$id" } - /** Bitwuzla does not distinguish between Bool and (BitVec 1). + /** + * Bitwuzla does not distinguish between Bool and (BitVec 1). * * By default, we convert all Bitwuzla (BitVec 1) terms as Bool expressions, but: * 1. user defined constant with (BitVec 1) sort may appear @@ -442,9 +454,9 @@ open class KBitwuzlaExprConverter( * For such reason, we introduce additional expressions * to convert from (BitVec 1) to Bool and vice versa. * - * @see ensureBoolExpr - * @see ensureBv1Expr - * @see ensureArrayExprSortMatch + * @see ensureBoolExpr + * @see ensureBv1Expr + * @see ensureArrayExprSortMatch * */ @Suppress("UNCHECKED_CAST") fun KExpr<*>.convertToBoolIfNeeded(): KExpr<*> = when (with(ctx) { sort }) { @@ -457,25 +469,28 @@ open class KBitwuzlaExprConverter( else -> this } - /** Convert expression to expected sort. + /** + * Convert expression to expected sort. * * Mainly used for convert from Bool to (BitVec 1): - * 1. in function app, when argument sort doesn't match - * 2. when top level expression expectedSort doesn't match ([convertExpr]) + * 1. In function app, when argument sort doesn't match + * 2. When top level expression expectedSort doesn't match ([convertExpr]) + * * Also works for Arrays. * - * @see convertToBoolIfNeeded + * @see convertToBoolIfNeeded * */ @Suppress("UNCHECKED_CAST") fun KExpr<*>.convertToExpectedIfNeeded(expected: T): KExpr = when (expected) { ctx.bv1Sort -> ensureBv1Expr() as KExpr ctx.boolSort -> ensureBoolExpr() as KExpr is KArraySort<*, *> -> { - (this as? KExpr> ?: error("array expected. actual is $this")) - .ensureArrayExprSortMatch( - domainExpected = { expected.domain }, - rangeExpected = { expected.range } - ) as KExpr + val array = this as? KExpr> ?: error("An array was expected. Actual is $this") + + array.ensureArrayExprSortMatch( + domainExpected = { expected.domain }, + rangeExpected = { expected.range } + ) as KExpr } else -> this as KExpr } @@ -490,6 +505,7 @@ open class KBitwuzlaExprConverter( ): KExpr<*> = with(ctx) { val expectedDomain = domainExpected(sort.domain) val expectedRange = rangeExpected(sort.range) + when { expectedDomain == sort.domain && expectedRange == sort.range -> this@ensureArrayExprSortMatch this@ensureArrayExprSortMatch is ArrayAdapterExpr<*, *, *, *> @@ -535,6 +551,7 @@ open class KBitwuzlaExprConverter( check(sort is KBvSort) { "Bv sort expected but $sort occurred" } this@ensureBvExpr } + @Suppress("UNCHECKED_CAST") expr as KExpr } @@ -548,7 +565,7 @@ open class KBitwuzlaExprConverter( builder.append(')') } - override fun accept(transformer: KTransformer): KExpr { + override fun accept(transformer: KTransformerBase): KExpr { check(transformer is AdapterTermRewriter) { "leaked adapter term" } return transformer.transform(this) } @@ -563,7 +580,7 @@ open class KBitwuzlaExprConverter( builder.append(')') } - override fun accept(transformer: KTransformer): KExpr { + override fun accept(transformer: KTransformerBase): KExpr { check(transformer is AdapterTermRewriter) { "leaked adapter term" } return transformer.transform(this) } @@ -584,7 +601,7 @@ open class KBitwuzlaExprConverter( builder.append(')') } - override fun accept(transformer: KTransformer): KExpr> { + override fun accept(transformer: KTransformerBase): KExpr> { check(transformer is AdapterTermRewriter) { "leaked adapter term" } return transformer.transform(this) } @@ -639,41 +656,47 @@ open class KBitwuzlaExprConverter( expr: ArrayAdapterExpr ): KExpr> = with(ctx) { val fromSort = expr.arg.sort - if (fromSort.domain == expr.toDomainSort && fromSort.range == expr.toRangeSort) { + + val exprDomainSort = expr.toDomainSort + val exprRangeSort = expr.toRangeSort + + if (fromSort.domain == exprDomainSort && fromSort.range == exprRangeSort) { return@with expr.arg as KExpr> } + val replacement = when (fromSort.domain) { bv1Sort, boolSort -> { // avoid lambda expression when possible - check(expr.toDomainSort == boolSort || expr.toDomainSort == bv1Sort) { - "unexpected cast from ${fromSort.domain} to ${expr.toDomainSort}" + check(exprDomainSort == boolSort || exprDomainSort == bv1Sort) { + "unexpected cast from ${fromSort.domain} to $exprDomainSort" } val falseValue = expr.arg.select(fromSort.domain.falseValue()) - .convertToExpectedIfNeeded(expr.toRangeSort) + .convertToExpectedIfNeeded(exprRangeSort) val trueValue = expr.arg.select(fromSort.domain.trueValue()) - .convertToExpectedIfNeeded(expr.toRangeSort) + .convertToExpectedIfNeeded(exprRangeSort) - val resultArraySort = mkArraySort(expr.toDomainSort, expr.toRangeSort) + val resultArraySort = mkArraySort(exprDomainSort, exprRangeSort) - mkArrayConst(resultArraySort, falseValue).store(expr.toDomainSort.trueValue(), trueValue) + mkArrayConst(resultArraySort, falseValue).store(exprDomainSort.trueValue(), trueValue) } else -> { - check(fromSort.domain == expr.toDomainSort) { - "unexpected cast from ${fromSort.domain} to ${expr.toDomainSort}" + check(fromSort.domain == exprDomainSort) { + "unexpected cast from ${fromSort.domain} to $exprDomainSort" } - val index = expr.toDomainSort.mkFreshConst("index") + val index = exprDomainSort.mkFreshConst("index") val bodyExpr = expr.arg.select(index as KExpr) - val body: KExpr = when (expr.toRangeSort) { + val body: KExpr = when (exprRangeSort) { bv1Sort -> bodyExpr.ensureBv1Expr() as KExpr boolSort -> bodyExpr.ensureBoolExpr() as KExpr - else -> error("unexpected domain: ${expr.toRangeSort}") + else -> error("unexpected domain: $exprRangeSort") } mkArrayLambda(index.decl, body) } } + AdapterTermRewriter(ctx).apply(replacement) } diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaExprInternalizer.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaExprInternalizer.kt index a92cf00da..e7d9cb5fc 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaExprInternalizer.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaExprInternalizer.kt @@ -4,6 +4,7 @@ import org.ksmt.KContext import org.ksmt.decl.KDecl import org.ksmt.decl.KDeclVisitor import org.ksmt.decl.KFuncDecl +import org.ksmt.expr.KAddArithExpr import org.ksmt.expr.KAndExpr import org.ksmt.expr.KArrayConst import org.ksmt.expr.KArrayLambda @@ -16,6 +17,7 @@ import org.ksmt.expr.KBitVec64Value import org.ksmt.expr.KBitVec8Value import org.ksmt.expr.KBitVecCustomValue import org.ksmt.expr.KBitVecNumberValue +import org.ksmt.expr.KBv2IntExpr import org.ksmt.expr.KBvAddExpr import org.ksmt.expr.KBvAddNoOverflowExpr import org.ksmt.expr.KBvAddNoUnderflowExpr @@ -53,6 +55,7 @@ import org.ksmt.expr.KBvSignedRemExpr import org.ksmt.expr.KBvSubExpr import org.ksmt.expr.KBvSubNoOverflowExpr import org.ksmt.expr.KBvSubNoUnderflowExpr +import org.ksmt.expr.KBvToFpExpr import org.ksmt.expr.KBvUnsignedDivExpr import org.ksmt.expr.KBvUnsignedGreaterExpr import org.ksmt.expr.KBvUnsignedGreaterOrEqualExpr @@ -64,17 +67,72 @@ import org.ksmt.expr.KBvXorExpr import org.ksmt.expr.KBvZeroExtensionExpr import org.ksmt.expr.KConst import org.ksmt.expr.KDistinctExpr +import org.ksmt.expr.KDivArithExpr import org.ksmt.expr.KEqExpr import org.ksmt.expr.KExistentialQuantifier import org.ksmt.expr.KExpr import org.ksmt.expr.KFalse +import org.ksmt.expr.KFp128Value +import org.ksmt.expr.KFp16Value +import org.ksmt.expr.KFp32Value +import org.ksmt.expr.KFp64Value +import org.ksmt.expr.KFpAbsExpr +import org.ksmt.expr.KFpAddExpr +import org.ksmt.expr.KFpCustomSizeValue +import org.ksmt.expr.KFpDivExpr +import org.ksmt.expr.KFpEqualExpr +import org.ksmt.expr.KFpFromBvExpr +import org.ksmt.expr.KFpFusedMulAddExpr +import org.ksmt.expr.KFpGreaterExpr +import org.ksmt.expr.KFpGreaterOrEqualExpr +import org.ksmt.expr.KFpIsInfiniteExpr +import org.ksmt.expr.KFpIsNaNExpr +import org.ksmt.expr.KFpIsNegativeExpr +import org.ksmt.expr.KFpIsNormalExpr +import org.ksmt.expr.KFpIsPositiveExpr +import org.ksmt.expr.KFpIsSubnormalExpr +import org.ksmt.expr.KFpIsZeroExpr +import org.ksmt.expr.KFpLessExpr +import org.ksmt.expr.KFpLessOrEqualExpr +import org.ksmt.expr.KFpMaxExpr +import org.ksmt.expr.KFpMinExpr +import org.ksmt.expr.KFpMulExpr +import org.ksmt.expr.KFpNegationExpr +import org.ksmt.expr.KFpRemExpr +import org.ksmt.expr.KFpRoundToIntegralExpr +import org.ksmt.expr.KFpRoundingModeExpr +import org.ksmt.expr.KFpSqrtExpr +import org.ksmt.expr.KFpSubExpr +import org.ksmt.expr.KFpToBvExpr +import org.ksmt.expr.KFpToFpExpr +import org.ksmt.expr.KFpToIEEEBvExpr +import org.ksmt.expr.KFpToRealExpr import org.ksmt.expr.KFunctionApp +import org.ksmt.expr.KFunctionAsArray +import org.ksmt.expr.KGeArithExpr +import org.ksmt.expr.KGtArithExpr import org.ksmt.expr.KImpliesExpr +import org.ksmt.expr.KInt32NumExpr +import org.ksmt.expr.KInt64NumExpr +import org.ksmt.expr.KIntBigNumExpr +import org.ksmt.expr.KIsIntRealExpr import org.ksmt.expr.KIteExpr +import org.ksmt.expr.KLeArithExpr +import org.ksmt.expr.KLtArithExpr +import org.ksmt.expr.KModIntExpr +import org.ksmt.expr.KMulArithExpr import org.ksmt.expr.KNotExpr import org.ksmt.expr.KOrExpr +import org.ksmt.expr.KPowerArithExpr import org.ksmt.expr.KQuantifier +import org.ksmt.expr.KRealNumExpr +import org.ksmt.expr.KRealToFpExpr +import org.ksmt.expr.KRemIntExpr +import org.ksmt.expr.KSubArithExpr +import org.ksmt.expr.KToIntRealExpr +import org.ksmt.expr.KToRealIntExpr import org.ksmt.expr.KTrue +import org.ksmt.expr.KUnaryMinusArithExpr import org.ksmt.expr.KUniversalQuantifier import org.ksmt.expr.KXorExpr import org.ksmt.solver.KSolverUnsupportedFeatureException @@ -84,6 +142,7 @@ import org.ksmt.solver.bitwuzla.bindings.BitwuzlaSort import org.ksmt.solver.bitwuzla.bindings.BitwuzlaTerm import org.ksmt.solver.bitwuzla.bindings.Native import org.ksmt.solver.util.KExprInternalizerBase +import org.ksmt.sort.KArithSort import org.ksmt.sort.KArraySort import org.ksmt.sort.KBoolSort import org.ksmt.sort.KBv16Sort @@ -91,6 +150,10 @@ import org.ksmt.sort.KBv32Sort import org.ksmt.sort.KBv64Sort import org.ksmt.sort.KBv8Sort import org.ksmt.sort.KBvSort +import org.ksmt.sort.KFp128Sort +import org.ksmt.sort.KFp16Sort +import org.ksmt.sort.KFp32Sort +import org.ksmt.sort.KFp64Sort import org.ksmt.sort.KFpRoundingModeSort import org.ksmt.sort.KFpSort import org.ksmt.sort.KIntSort @@ -100,7 +163,7 @@ import org.ksmt.sort.KSortVisitor import org.ksmt.sort.KUninterpretedSort open class KBitwuzlaExprInternalizer( - override val ctx: KContext, + private val ctx: KContext, val bitwuzlaCtx: KBitwuzlaContext ) : KExprInternalizerBase() { @@ -117,33 +180,34 @@ open class KBitwuzlaExprInternalizer( saveExprInternalizationResult(expr, internalized) } - /* - * Create Bitwuzla term from KSmt expression + /** + * Create Bitwuzla term from KSMT expression * */ fun KExpr.internalize(): BitwuzlaTerm { bitwuzlaCtx.ensureActive() return internalizeExpr() } - /* - * Create Bitwuzla sort from KSmt sort + /** + * Create Bitwuzla sort from KSMT sort * */ fun T.internalizeSort(): BitwuzlaSort = accept(sortInternalizer) - /* - * Create Bitwuzla function sort for KSmt declaration. - * If declaration is a constant then nonfunction sort is returned + /** + * Create Bitwuzla function sort for KSMT declaration. + * + * If [this] declaration is a constant then non-function sort is returned * */ fun KDecl.bitwuzlaFunctionSort(): BitwuzlaSort = accept(functionSortInternalizer) - fun saveExprInternalizationResult(expr: KExpr<*>, term: BitwuzlaTerm) { + private fun saveExprInternalizationResult(expr: KExpr<*>, term: BitwuzlaTerm) { bitwuzlaCtx.internalizeExpr(expr) { term } val kind = Native.bitwuzlaTermGetKind(term) - /** + /* * Save internalized values for [KBitwuzlaExprConverter] needs * @see [KBitwuzlaContext.saveInternalizedValue] - * */ + */ if (kind != BitwuzlaKind.BITWUZLA_KIND_VAL) return if (bitwuzlaCtx.convertValue(term) != null) return @@ -153,17 +217,11 @@ open class KBitwuzlaExprInternalizer( } } - /** - * [KBitwuzlaExprInternalizer] overrides transform for all supported Bitwuzla expressions. - * Therefore, if basic expr transform is invoked expression is unsupported. - * */ - override fun transformExpr(expr: KExpr): KExpr = - error("Unsupported expr $expr") - override fun transform(expr: KFunctionApp): KExpr = with(expr) { transformList(args) { args: Array -> val const = bitwuzlaCtx.mkConstant(decl, decl.bitwuzlaFunctionSort()) val termArgs = (listOf(const) + args).toTypedArray() + Native.bitwuzlaMkTerm(bitwuzlaCtx.bitwuzla, BitwuzlaKind.BITWUZLA_KIND_APPLY, termArgs) } } @@ -376,7 +434,8 @@ open class KBitwuzlaExprInternalizer( transform(value) { arg: BitwuzlaTerm -> Native.bitwuzlaMkTerm1Indexed2( bitwuzlaCtx.bitwuzla, BitwuzlaKind.BITWUZLA_KIND_BV_EXTRACT, - arg, expr.high, expr.low + arg, + high, low ) } } @@ -385,7 +444,8 @@ open class KBitwuzlaExprInternalizer( transform(value) { arg: BitwuzlaTerm -> Native.bitwuzlaMkTerm1Indexed1( bitwuzlaCtx.bitwuzla, BitwuzlaKind.BITWUZLA_KIND_BV_SIGN_EXTEND, - arg, expr.i + arg, + extensionSize ) } } @@ -394,7 +454,8 @@ open class KBitwuzlaExprInternalizer( transform(value) { arg: BitwuzlaTerm -> Native.bitwuzlaMkTerm1Indexed1( bitwuzlaCtx.bitwuzla, BitwuzlaKind.BITWUZLA_KIND_BV_ZERO_EXTEND, - arg, expr.i + arg, + extensionSize ) } } @@ -403,7 +464,8 @@ open class KBitwuzlaExprInternalizer( transform(value) { arg: BitwuzlaTerm -> Native.bitwuzlaMkTerm1Indexed1( bitwuzlaCtx.bitwuzla, BitwuzlaKind.BITWUZLA_KIND_BV_REPEAT, - arg, expr.i + arg, + repeatNumber ) } } @@ -432,7 +494,8 @@ open class KBitwuzlaExprInternalizer( transform(value) { arg: BitwuzlaTerm -> Native.bitwuzlaMkTerm1Indexed1( bitwuzlaCtx.bitwuzla, BitwuzlaKind.BITWUZLA_KIND_BV_ROLI, - arg, expr.i + arg, + rotationNumber ) } } @@ -441,7 +504,8 @@ open class KBitwuzlaExprInternalizer( transform(value) { arg: BitwuzlaTerm -> Native.bitwuzlaMkTerm1Indexed1( bitwuzlaCtx.bitwuzla, BitwuzlaKind.BITWUZLA_KIND_BV_RORI, - arg, expr.i + arg, + rotationNumber ) } } @@ -455,25 +519,22 @@ open class KBitwuzlaExprInternalizer( transform(arg0, arg1, kind) } - override fun transform(expr: KBvAddNoUnderflowExpr) = with(expr) { + override fun transform(expr: KBvAddNoUnderflowExpr) = TODO("no direct support for $expr") - } override fun transform(expr: KBvSubNoOverflowExpr) = with(expr) { transform(arg0, arg1, BitwuzlaKind.BITWUZLA_KIND_BV_SSUB_OVERFLOW) } - override fun transform(expr: KBvSubNoUnderflowExpr) = with(expr) { + override fun transform(expr: KBvSubNoUnderflowExpr) = TODO("no direct support for $expr") - } override fun transform(expr: KBvDivNoOverflowExpr) = with(expr) { transform(arg0, arg1, BitwuzlaKind.BITWUZLA_KIND_BV_SDIV_OVERFLOW) } - override fun transform(expr: KBvNegNoOverflowExpr) = with(expr) { + override fun transform(expr: KBvNegNoOverflowExpr) = TODO("no direct support for $expr") - } override fun transform(expr: KBvMulNoOverflowExpr) = with(expr) { val kind = if (isSigned) { @@ -481,12 +542,12 @@ open class KBitwuzlaExprInternalizer( } else { BitwuzlaKind.BITWUZLA_KIND_BV_UMUL_OVERFLOW } + transform(arg0, arg1, kind) } - override fun transform(expr: KBvMulNoUnderflowExpr) = with(expr) { + override fun transform(expr: KBvMulNoUnderflowExpr) = TODO("no direct support for $expr") - } override fun transform(expr: KArrayStore) = with(expr) { transform(array, index, value, BitwuzlaKind.BITWUZLA_KIND_ARRAY_STORE) @@ -512,30 +573,269 @@ open class KBitwuzlaExprInternalizer( body.internalize() } val bodyKind = Native.bitwuzlaTermGetKind(body) + if (bodyKind == BitwuzlaKind.BITWUZLA_KIND_ARRAY_SELECT) { val selectArgs = Native.bitwuzlaTermGetChildren(body) if (selectArgs[1] == indexVar) { - /** Recognize and support special case of lambda expressions - * which can be produced by [KBitwuzlaExprConverter]. - * - * (lambda (i) (select array i)) -> array + /* + Recognize and support special case of lambda expressions + which can be produced by [KBitwuzlaExprConverter]. + + (lambda (i) (select array i)) -> array */ return@transform selectArgs[0] } } + throw KSolverUnsupportedFeatureException("array lambda expressions are not supported in Bitwuzla") } } } - override fun transform(expr: KExistentialQuantifier): KExpr = expr.internalizeQuantifier { args -> + override fun transform( + expr: KExistentialQuantifier + ): KExpr = expr.internalizeQuantifier { args -> Native.bitwuzlaMkTerm(bitwuzlaCtx.bitwuzla, BitwuzlaKind.BITWUZLA_KIND_EXISTS, args) } - override fun transform(expr: KUniversalQuantifier): KExpr = expr.internalizeQuantifier { args -> + override fun transform( + expr: KUniversalQuantifier + ): KExpr = expr.internalizeQuantifier { args -> Native.bitwuzlaMkTerm(bitwuzlaCtx.bitwuzla, BitwuzlaKind.BITWUZLA_KIND_FORALL, args) } + override fun transform(expr: KBv2IntExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KFpToRealExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KRealToFpExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KModIntExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KRemIntExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KToRealIntExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KInt32NumExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KInt64NumExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KIntBigNumExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KToIntRealExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KIsIntRealExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KRealNumExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun > transform(expr: KAddArithExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun > transform(expr: KMulArithExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun > transform(expr: KSubArithExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun > transform(expr: KUnaryMinusArithExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun > transform(expr: KDivArithExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun > transform(expr: KPowerArithExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun > transform(expr: KLtArithExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun > transform(expr: KLeArithExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun > transform(expr: KGtArithExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun > transform(expr: KGeArithExpr): KExpr { + throw KSolverUnsupportedFeatureException("int and real theories are not supported in Bitwuzla") + } + + override fun transform(expr: KFp16Value): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFp32Value): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFp64Value): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFp128Value): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpCustomSizeValue): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpRoundingModeExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpAbsExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpNegationExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpAddExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpSubExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpMulExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpDivExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpFusedMulAddExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpSqrtExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpRemExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpRoundToIntegralExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpMinExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpMaxExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpLessOrEqualExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpLessExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpGreaterOrEqualExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpGreaterExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpEqualExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpIsNormalExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpIsSubnormalExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpIsZeroExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpIsInfiniteExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpIsNaNExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpIsNegativeExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpIsPositiveExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpToBvExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpToIEEEBvExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpFromBvExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFpToFpExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KBvToFpExpr): KExpr { + TODO("Fp theory is not yet supported in bitwuzla") + } + + override fun transform(expr: KFunctionAsArray): KExpr> { + TODO("KFunctionAsArray internalization is not implemented in bitwuzla") + } + inline fun T.internalizeQuantifier( crossinline internalizer: T.(Array) -> BitwuzlaTerm ) = transform { @@ -547,8 +847,11 @@ open class KBitwuzlaExprInternalizer( val body = with(bodyInternalizer) { body.internalize() } + if (bounds.isEmpty()) return@transform body + val args = (boundVars + body).toTypedArray() + internalizer(args) } } @@ -563,18 +866,21 @@ open class KBitwuzlaExprInternalizer( if (sort.range is KArraySort<*, *> || sort.domain is KArraySort<*, *>) { throw KSolverUnsupportedFeatureException("Bitwuzla doesn't support nested arrays") } + val domain = sort.domain.accept(this@SortInternalizer) val range = sort.range.accept(this@SortInternalizer) + Native.bitwuzlaMkArraySort(bitwuzlaCtx.bitwuzla, domain, range) } override fun visit(sort: S): BitwuzlaSort = bitwuzlaCtx.internalizeSort(sort) { val size = sort.sizeBits.toInt() + if (size == 1) { bitwuzlaCtx.boolSort } else { - Native.bitwuzlaMkBvSort(bitwuzlaCtx.bitwuzla, sort.sizeBits.toInt()) + Native.bitwuzlaMkBvSort(bitwuzlaCtx.bitwuzla, size) } } @@ -606,12 +912,16 @@ open class KBitwuzlaExprInternalizer( if (decl.argSorts.any { it is KArraySort<*, *> }) { throw KSolverUnsupportedFeatureException("Bitwuzla doesn't support functions with arrays in domain") } + if (decl.argSorts.isNotEmpty() && decl.sort is KArraySort<*, *>) { throw KSolverUnsupportedFeatureException("Bitwuzla doesn't support functions with arrays in range") } + val domain = decl.argSorts.map { it.accept(sortInternalizer) }.toTypedArray() val range = decl.sort.accept(sortInternalizer) + if (domain.isEmpty()) return@internalizeDeclSort range + Native.bitwuzlaMkFunSort(bitwuzlaCtx.bitwuzla, domain.size, domain, range) } } diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaModel.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaModel.kt index d73d06d27..c52870da3 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaModel.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaModel.kt @@ -25,15 +25,17 @@ open class KBitwuzlaModel( private val interpretations: MutableMap, KModel.KFuncInterp<*>> = hashMapOf() - override fun eval(expr: KExpr, complete: Boolean): KExpr = bitwuzlaCtx.bitwuzlaTry { + override fun eval(expr: KExpr, isComplete: Boolean): KExpr = bitwuzlaCtx.bitwuzlaTry { with(ctx) { bitwuzlaCtx.ensureActive() + val term = with(internalizer) { expr.internalize() } val value = Native.bitwuzlaGetValue(bitwuzlaCtx.bitwuzla, term) + with(converter) { val convertedExpr = value.convertExpr(expr.sort) - if (!complete) return convertedExpr + if (!isComplete) return convertedExpr convertedExpr.accept(ModelCompleter(expr, incompleteDecls)) } @@ -41,13 +43,17 @@ open class KBitwuzlaModel( } @Suppress("UNCHECKED_CAST") - override fun interpretation(decl: KDecl): KModel.KFuncInterp = interpretations.getOrPut(decl) { - bitwuzlaCtx.bitwuzlaTry { - with(ctx) { + override fun interpretation( + decl: KDecl + ): KModel.KFuncInterp = with(ctx) { + val interpretation = interpretations.getOrPut(decl) { + bitwuzlaCtx.bitwuzlaTry { bitwuzlaCtx.ensureActive() + val term = with(internalizer) { bitwuzlaCtx.mkConstant(decl, decl.bitwuzlaFunctionSort()) } + when { Native.bitwuzlaTermIsArray(term) -> arrayInterpretation(decl, term) Native.bitwuzlaTermIsFun(term) -> functionInterpretation(decl, term) @@ -64,56 +70,70 @@ open class KBitwuzlaModel( } } } - } as KModel.KFuncInterp - - private fun functionInterpretation(decl: KDecl, term: BitwuzlaTerm): KModel.KFuncInterp = - with(converter) { - check(decl is KFuncDecl) { "function expected but actual is $decl" } - val entries = mutableListOf>() - val interp = Native.bitwuzlaGetFunValue(bitwuzlaCtx.bitwuzla, term) - check(interp.arity == decl.argSorts.size) { - "function arity mismatch: ${interp.arity} and ${decl.argSorts.size}" - } - for (i in 0 until interp.size) { - val args = interp.args[i].zip(decl.argSorts) { arg, sort -> arg.convertExpr(sort) } - val value = interp.values[i].convertExpr(decl.sort) - entries += KModel.KFuncInterpEntry(args, value) - } - KModel.KFuncInterp( - sort = decl.sort, - vars = emptyList(), - entries = entries, - default = null - ) + + interpretation as KModel.KFuncInterp + } + + private fun functionInterpretation( + decl: KDecl, + term: BitwuzlaTerm + ): KModel.KFuncInterp = with(converter) { + check(decl is KFuncDecl) { "function expected but actual is $decl" } + + val entries = mutableListOf>() + val interp = Native.bitwuzlaGetFunValue(bitwuzlaCtx.bitwuzla, term) + + check(interp.arity == decl.argSorts.size) { + "function arity mismatch: ${interp.arity} and ${decl.argSorts.size}" + } + + for (i in 0 until interp.size) { + val args = interp.args[i].zip(decl.argSorts) { arg, sort -> arg.convertExpr(sort) } + val value = interp.values[i].convertExpr(decl.sort) + entries += KModel.KFuncInterpEntry(args, value) } + KModel.KFuncInterp( + sort = decl.sort, + vars = emptyList(), + entries = entries, + default = null + ) + } + @Suppress("UNCHECKED_CAST") - private fun KContext.arrayInterpretation(decl: KDecl, term: BitwuzlaTerm): KModel.KFuncInterp = - with(converter) { - val sort = decl.sort as KArraySort<*, *> - val entries = mutableListOf>() - val interp = Native.bitwuzlaGetArrayValue(bitwuzlaCtx.bitwuzla, term) - for (i in 0 until interp.size) { - val index = interp.indices[i].convertExpr(sort.domain) - val value = interp.values[i].convertExpr(sort.range) - entries += KModel.KFuncInterpEntry(listOf(index), value) - } - val default = interp.defaultValue?.convertExpr(sort.range) - val arrayInterpDecl = mkFreshFuncDecl("array", sort.range, listOf(sort.domain)) - interpretations[arrayInterpDecl] = KModel.KFuncInterp( - sort = sort.range, - vars = emptyList(), - entries = entries, - default = default - ) - KModel.KFuncInterp( - sort = decl.sort, - vars = emptyList(), - entries = emptyList(), - default = mkFunctionAsArray(arrayInterpDecl) as KExpr - ) + private fun KContext.arrayInterpretation( + decl: KDecl, + term: BitwuzlaTerm + ): KModel.KFuncInterp = with(converter) { + val sort = decl.sort as KArraySort<*, *> + val entries = mutableListOf>() + val interp = Native.bitwuzlaGetArrayValue(bitwuzlaCtx.bitwuzla, term) + + for (i in 0 until interp.size) { + val index = interp.indices[i].convertExpr(sort.domain) + val value = interp.values[i].convertExpr(sort.range) + entries += KModel.KFuncInterpEntry(listOf(index), value) } + val default = interp.defaultValue?.convertExpr(sort.range) + val arrayInterpDecl = mkFreshFuncDecl("array", sort.range, listOf(sort.domain)) + + interpretations[arrayInterpDecl] = KModel.KFuncInterp( + sort = sort.range, + vars = emptyList(), + entries = entries, + default = default + ) + + KModel.KFuncInterp( + sort = decl.sort, + vars = emptyList(), + entries = emptyList(), + default = mkFunctionAsArray(arrayInterpDecl) as KExpr + ) + } + override fun detach(): KModel { declarations.forEach { interpretation(it) } return KModelImpl(ctx, interpretations.toMutableMap()) @@ -124,20 +144,28 @@ open class KBitwuzlaModel( KModelEvaluator(ctx, modelStub, true) } - /** Generate concrete values instead of unknown constants. + /** + * Generate concrete values instead of unknown constants. * */ inner class ModelCompleter( private val evaluatedExpr: KExpr<*>, private val incompleteDecls: Set> ) : KTransformer { override val ctx: KContext = this@KBitwuzlaModel.ctx + override fun transformExpr(expr: KExpr): KExpr = with(ctx) { - if (expr == evaluatedExpr) return with(valueSampler) { expr.sort.sampleValue() } + if (expr == evaluatedExpr) { + return with(valueSampler) { expr.sort.sampleValue() } + } + return super.transformExpr(expr) } override fun transformApp(expr: KApp): KExpr = with(ctx) { - if (expr.decl in incompleteDecls) return with(valueSampler) { expr.sort.sampleValue() } + if (expr.decl in incompleteDecls) { + return with(valueSampler) { expr.sort.sampleValue() } + } + return super.transformApp(expr) } } diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaSolver.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaSolver.kt index b67996a50..b5dfec4e0 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaSolver.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/KBitwuzlaSolver.kt @@ -23,11 +23,11 @@ open class KBitwuzlaSolver(private val ctx: KContext) : KSolver { private var lastCheckStatus = KSolverStatus.UNKNOWN init { - Native.bitwuzlaSetOption(bitwuzlaCtx.bitwuzla, BitwuzlaOption.BITWUZLA_OPT_PRODUCE_MODELS, 1) - Native.bitwuzlaSetOption(bitwuzlaCtx.bitwuzla, BitwuzlaOption.BITWUZLA_OPT_PRODUCE_UNSAT_CORES, 1) + Native.bitwuzlaSetOption(bitwuzlaCtx.bitwuzla, BitwuzlaOption.BITWUZLA_OPT_PRODUCE_MODELS, value = 1) + Native.bitwuzlaSetOption(bitwuzlaCtx.bitwuzla, BitwuzlaOption.BITWUZLA_OPT_PRODUCE_UNSAT_CORES, value = 1) } - private var currentLevelTrackedAssertions = mutableSetOf() + private var currentLevelTrackedAssertions = hashSetOf() private val trackedAssertions = mutableListOf(currentLevelTrackedAssertions) override fun assert(expr: KExpr) = bitwuzlaCtx.bitwuzlaTry { @@ -40,6 +40,7 @@ open class KBitwuzlaSolver(private val ctx: KContext) : KSolver { val trackedExpr = with(ctx) { !trackVar or expr } val exprTerm = with(exprInternalizer) { trackedExpr.internalize() } val trackVarTerm = with(exprInternalizer) { trackVar.internalize() } + currentLevelTrackedAssertions += trackVarTerm Native.bitwuzlaAssert(bitwuzlaCtx.bitwuzla, exprTerm) @@ -51,14 +52,14 @@ open class KBitwuzlaSolver(private val ctx: KContext) : KSolver { override fun push(): Unit = bitwuzlaCtx.bitwuzlaTry { Native.bitwuzlaPush(bitwuzlaCtx.bitwuzla, nlevels = 1) - currentLevelTrackedAssertions = mutableSetOf() + currentLevelTrackedAssertions = hashSetOf() trackedAssertions.add(currentLevelTrackedAssertions) } override fun pop(n: UInt): Unit = bitwuzlaCtx.bitwuzlaTry { val currentLevel = trackedAssertions.lastIndex.toUInt() require(n <= currentLevel) { - "Can not pop $n scope levels because current scope level is $currentLevel" + "Cannot pop $n scope levels because current scope level is $currentLevel" } if (n == 0u) return @@ -95,16 +96,21 @@ open class KBitwuzlaSolver(private val ctx: KContext) : KSolver { override fun unsatCore(): List> = bitwuzlaCtx.bitwuzlaTry { require(lastCheckStatus == KSolverStatus.UNSAT) { "Unsat cores are only available after UNSAT checks" } + val fullCore = Native.bitwuzlaGetUnsatCore(bitwuzlaCtx.bitwuzla) val trackVars = trackedAssertions.flatten().toSet() val onlyTrackedAssertions = fullCore.filter { it in trackVars } val unsatAssumptions = Native.bitwuzlaGetUnsatAssumptions(bitwuzlaCtx.bitwuzla) val unsatCore = onlyTrackedAssertions + unsatAssumptions + return with(exprConverter) { unsatCore.map { it.convertExpr(ctx.boolSort) } } } override fun reasonOfUnknown(): String = bitwuzlaCtx.bitwuzlaTry { - require(lastCheckStatus == KSolverStatus.UNKNOWN) { "Unknown reason is only available after UNKNOWN checks" } + require(lastCheckStatus == KSolverStatus.UNKNOWN) { + "Unknown reason is only available after UNKNOWN checks" + } + // There is no way to retrieve reason of unknown from Bitwuzla in general case. return "unknown" } diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaBVBase.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaBVBase.kt index 77faba524..e5b4438d4 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaBVBase.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaBVBase.kt @@ -1,4 +1,5 @@ @file:Suppress("MagicNumber") + package org.ksmt.solver.bitwuzla.bindings /** diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaKind.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaKind.kt index cf272d1e0..e1015eb02 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaKind.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaKind.kt @@ -1,20 +1,21 @@ @file:Suppress("MagicNumber") + package org.ksmt.solver.bitwuzla.bindings /** * The term kind. */ enum class BitwuzlaKind(val value: Int) { - /** First order constant. */ + /** First order constant. */ BITWUZLA_KIND_CONST(0), - /** Constant array. */ + /** Constant array. */ BITWUZLA_KIND_CONST_ARRAY(1), - /** Value. */ + /** Value. */ BITWUZLA_KIND_VAL(2), - /** Bound variable. */ + /** Bound variable. */ BITWUZLA_KIND_VAR(3), /** @@ -24,55 +25,55 @@ enum class BitwuzlaKind(val value: Int) { */ BITWUZLA_KIND_AND(4), - /** Function application. */ + /** Function application. */ BITWUZLA_KIND_APPLY(5), /** * Array select. * - * SMT-LIB: `select` + * SMT-LIB: `select` */ BITWUZLA_KIND_ARRAY_SELECT(6), /** * Array store. * - * SMT-LIB: `store` + * SMT-LIB: `store` */ BITWUZLA_KIND_ARRAY_STORE(7), /** * Bit-vector addition. * - * SMT-LIB: `bvadd` + * SMT-LIB: `bvadd` */ BITWUZLA_KIND_BV_ADD(8), /** * Bit-vector and. * - * SMT-LIB: `bvand` + * SMT-LIB: `bvand` */ BITWUZLA_KIND_BV_AND(9), /** * Bit-vector arithmetic right shift. * - * SMT-LIB: `bvashr` + * SMT-LIB: `bvashr` */ BITWUZLA_KIND_BV_ASHR(10), /** * Bit-vector comparison. * - * SMT-LIB: `bvcomp` + * SMT-LIB: `bvcomp` */ BITWUZLA_KIND_BV_COMP(11), /** * Bit-vector concat. * - * SMT-LIB: `concat` + * SMT-LIB: `concat` */ BITWUZLA_KIND_BV_CONCAT(12), @@ -93,42 +94,42 @@ enum class BitwuzlaKind(val value: Int) { /** * Bit-vector multiplication. * - * SMT-LIB: `bvmul` + * SMT-LIB: `bvmul` */ BITWUZLA_KIND_BV_MUL(15), /** * Bit-vector nand. * - * SMT-LIB: `bvnand` + * SMT-LIB: `bvnand` */ BITWUZLA_KIND_BV_NAND(16), /** * Bit-vector negation (two's complement). * - * SMT-LIB: `bvneg` + * SMT-LIB: `bvneg` */ BITWUZLA_KIND_BV_NEG(17), /** * Bit-vector nor. * - * SMT-LIB: `bvnor` + * SMT-LIB: `bvnor` */ BITWUZLA_KIND_BV_NOR(18), /** * Bit-vector not (one's complement). * - * SMT-LIB: `bvnot` + * SMT-LIB: `bvnot` */ BITWUZLA_KIND_BV_NOT(19), /** * Bit-vector or. * - * SMT-LIB: `bvor` + * SMT-LIB: `bvor` */ BITWUZLA_KIND_BV_OR(20), @@ -190,70 +191,70 @@ enum class BitwuzlaKind(val value: Int) { /** * Bit-vector signed division. * - * SMT-LIB: `bvsdiv` + * SMT-LIB: `bvsdiv` */ BITWUZLA_KIND_BV_SDIV(28), /** * Bit-vector signed greater than or equal. * - * SMT-LIB: `bvsle` + * SMT-LIB: `bvsle` */ BITWUZLA_KIND_BV_SGE(29), /** * Bit-vector signed greater than. * - * SMT-LIB: `bvslt` + * SMT-LIB: `bvslt` */ BITWUZLA_KIND_BV_SGT(30), /** * Bit-vector logical left shift. * - * SMT-LIB: `bvshl` + * SMT-LIB: `bvshl` */ BITWUZLA_KIND_BV_SHL(31), /** * Bit-vector logical right shift. * - * SMT-LIB: `bvshr` + * SMT-LIB: `bvshr` */ BITWUZLA_KIND_BV_SHR(32), /** * Bit-vector signed less than or equal. * - * SMT-LIB: `bvsle` + * SMT-LIB: `bvsle` */ BITWUZLA_KIND_BV_SLE(33), /** * Bit-vector signed less than. * - * SMT-LIB: `bvslt` + * SMT-LIB: `bvslt` */ BITWUZLA_KIND_BV_SLT(34), /** * Bit-vector signed modulo. * - * SMT-LIB: `bvsmod` + * SMT-LIB: `bvsmod` */ BITWUZLA_KIND_BV_SMOD(35), /** * Bit-vector signed multiplication overflow test. * - * SMT-LIB: `bvsmod` + * SMT-LIB: `bvsmod` */ BITWUZLA_KIND_BV_SMUL_OVERFLOW(36), /** * Bit-vector signed remainder. * - * SMT-LIB: `bvsrem` + * SMT-LIB: `bvsrem` */ BITWUZLA_KIND_BV_SREM(37), @@ -267,7 +268,7 @@ enum class BitwuzlaKind(val value: Int) { /** * Bit-vector subtraction. * - * SMT-LIB: `bvsub` + * SMT-LIB: `bvsub` */ BITWUZLA_KIND_BV_SUB(39), @@ -281,35 +282,35 @@ enum class BitwuzlaKind(val value: Int) { /** * Bit-vector unsigned division. * - * SMT-LIB: `bvudiv` + * SMT-LIB: `bvudiv` */ BITWUZLA_KIND_BV_UDIV(41), /** * Bit-vector unsigned greater than or equal. * - * SMT-LIB: `bvuge` + * SMT-LIB: `bvuge` */ BITWUZLA_KIND_BV_UGE(42), /** * Bit-vector unsigned greater than. * - * SMT-LIB: `bvugt` + * SMT-LIB: `bvugt` */ BITWUZLA_KIND_BV_UGT(43), /** * Bit-vector unsigned less than or equal. * - * SMT-LIB: `bvule` + * SMT-LIB: `bvule` */ BITWUZLA_KIND_BV_ULE(44), /** * Bit-vector unsigned less than. * - * SMT-LIB: `bvult` + * SMT-LIB: `bvult` */ BITWUZLA_KIND_BV_ULT(45), @@ -323,7 +324,7 @@ enum class BitwuzlaKind(val value: Int) { /** * Bit-vector unsigned remainder. * - * SMT-LIB: `bvurem` + * SMT-LIB: `bvurem` */ BITWUZLA_KIND_BV_UREM(47), @@ -337,346 +338,346 @@ enum class BitwuzlaKind(val value: Int) { /** * Bit-vector xnor. * - * SMT-LIB: `bvxnor` + * SMT-LIB: `bvxnor` */ BITWUZLA_KIND_BV_XNOR(49), /** * Bit-vector xor. * - * SMT-LIB: `bvxor` + * SMT-LIB: `bvxor` */ BITWUZLA_KIND_BV_XOR(50), /** * Disequality. * - * SMT-LIB: `distinct` + * SMT-LIB: `distinct` */ BITWUZLA_KIND_DISTINCT(51), /** * Equality. * - * SMT-LIB: `=` + * SMT-LIB: `=` */ BITWUZLA_KIND_EQUAL(52), /** * Existential quantification. * - * SMT-LIB: `exists` + * SMT-LIB: `exists` */ BITWUZLA_KIND_EXISTS(53), /** * Universal quantification. * - * SMT-LIB: `forall` + * SMT-LIB: `forall` */ BITWUZLA_KIND_FORALL(54), /** * Floating-point absolute value. * - * SMT-LIB: `fp.abs` + * SMT-LIB: `fp.abs` */ BITWUZLA_KIND_FP_ABS(55), /** * Floating-point addition. * - * SMT-LIB: `fp.add` + * SMT-LIB: `fp.add` */ BITWUZLA_KIND_FP_ADD(56), /** * Floating-point division. * - * SMT-LIB: `fp.div` + * SMT-LIB: `fp.div` */ BITWUZLA_KIND_FP_DIV(57), /** * Floating-point equality. * - * SMT-LIB: `fp.eq` + * SMT-LIB: `fp.eq` */ BITWUZLA_KIND_FP_EQ(58), /** * Floating-point fused multiplcation and addition. * - * SMT-LIB: `fp.fma` + * SMT-LIB: `fp.fma` */ BITWUZLA_KIND_FP_FMA(59), /** * Floating-point IEEE 754 value. * - * SMT-LIB: `fp` + * SMT-LIB: `fp` */ BITWUZLA_KIND_FP_FP(60), /** * Floating-point greater than or equal. * - * SMT-LIB: `fp.geq` + * SMT-LIB: `fp.geq` */ BITWUZLA_KIND_FP_GEQ(61), /** * Floating-point greater than. * - * SMT-LIB: `fp.gt` + * SMT-LIB: `fp.gt` */ BITWUZLA_KIND_FP_GT(62), /** * Floating-point is infinity tester. * - * SMT-LIB: `fp.isInfinite` + * SMT-LIB: `fp.isInfinite` */ BITWUZLA_KIND_FP_IS_INF(63), /** * Floating-point is Nan tester. * - * SMT-LIB: `fp.isNaN` + * SMT-LIB: `fp.isNaN` */ BITWUZLA_KIND_FP_IS_NAN(64), /** * Floating-point is negative tester. * - * SMT-LIB: `fp.isNegative` + * SMT-LIB: `fp.isNegative` */ BITWUZLA_KIND_FP_IS_NEG(65), /** * Floating-point is normal tester. * - * SMT-LIB: `fp.isNormal` + * SMT-LIB: `fp.isNormal` */ BITWUZLA_KIND_FP_IS_NORMAL(66), /** * Floating-point is positive tester. * - * SMT-LIB: `fp.isPositive` + * SMT-LIB: `fp.isPositive` */ BITWUZLA_KIND_FP_IS_POS(67), /** * Floating-point is subnormal tester. * - * SMT-LIB: `fp.isSubnormal` + * SMT-LIB: `fp.isSubnormal` */ BITWUZLA_KIND_FP_IS_SUBNORMAL(68), /** * Floating-point is zero tester. * - * SMT-LIB: `fp.isZero` + * SMT-LIB: `fp.isZero` */ BITWUZLA_KIND_FP_IS_ZERO(69), /** * Floating-point less than or equal. * - * SMT-LIB: `fp.leq` + * SMT-LIB: `fp.leq` */ BITWUZLA_KIND_FP_LEQ(70), /** * Floating-point less than. * - * SMT-LIB: `fp.lt` + * SMT-LIB: `fp.lt` */ BITWUZLA_KIND_FP_LT(71), /** * Floating-point max. * - * SMT-LIB: `fp.max` + * SMT-LIB: `fp.max` */ BITWUZLA_KIND_FP_MAX(72), /** * Floating-point min. * - * SMT-LIB: `fp.min` + * SMT-LIB: `fp.min` */ BITWUZLA_KIND_FP_MIN(73), /** * Floating-point multiplcation. * - * SMT-LIB: `fp.mul` + * SMT-LIB: `fp.mul` */ BITWUZLA_KIND_FP_MUL(74), /** * Floating-point negation. * - * SMT-LIB: `fp.neg` + * SMT-LIB: `fp.neg` */ BITWUZLA_KIND_FP_NEG(75), /** * Floating-point remainder. * - * SMT-LIB: `fp.rem` + * SMT-LIB: `fp.rem` */ BITWUZLA_KIND_FP_REM(76), /** * Floating-point round to integral. * - * SMT-LIB: `fp.roundToIntegral` + * SMT-LIB: `fp.roundToIntegral` */ BITWUZLA_KIND_FP_RTI(77), /** * Floating-point round to square root. * - * SMT-LIB: `fp.sqrt` + * SMT-LIB: `fp.sqrt` */ BITWUZLA_KIND_FP_SQRT(78), /** * Floating-point round to subtraction. * - * SMT-LIB: `fp.sqrt` + * SMT-LIB: `fp.sqrt` */ BITWUZLA_KIND_FP_SUB(79), /** * Boolean if and only if. * - * SMT-LIB: `=` + * SMT-LIB: `=` */ BITWUZLA_KIND_IFF(80), /** * Boolean implies. * - * SMT-LIB: `=>` + * SMT-LIB: `=>` */ BITWUZLA_KIND_IMPLIES(81), /** * If-then-else. * - * SMT-LIB: `ite` + * SMT-LIB: `ite` */ BITWUZLA_KIND_ITE(82), - /** Lambda. */ + /** Lambda. */ BITWUZLA_KIND_LAMBDA(83), /** * Boolean not. * - * SMT-LIB: `not` + * SMT-LIB: `not` */ BITWUZLA_KIND_NOT(84), /** * Boolean or. * - * SMT-LIB: `or` + * SMT-LIB: `or` */ BITWUZLA_KIND_OR(85), /** * Boolean xor. * - * SMT-LIB: `xor` + * SMT-LIB: `xor` */ BITWUZLA_KIND_XOR(86), /** * Bit-vector extract. * - * SMT-LIB: `extract` (indexed) + * SMT-LIB: `extract` (indexed) */ BITWUZLA_KIND_BV_EXTRACT(87), /** * Bit-vector repeat. * - * SMT-LIB: `repeat` (indexed) + * SMT-LIB: `repeat` (indexed) */ BITWUZLA_KIND_BV_REPEAT(88), /** * Bit-vector rotate left by integer. * - * SMT-LIB: `rotate_left` (indexed) + * SMT-LIB: `rotate_left` (indexed) */ BITWUZLA_KIND_BV_ROLI(89), /** * Bit-vector rotate right by integer. * - * SMT-LIB: `rotate_right` (indexed) + * SMT-LIB: `rotate_right` (indexed) */ BITWUZLA_KIND_BV_RORI(90), /** * Bit-vector sign extend. * - * SMT-LIB: `sign_extend` (indexed) + * SMT-LIB: `sign_extend` (indexed) */ BITWUZLA_KIND_BV_SIGN_EXTEND(91), /** * Bit-vector zero extend. * - * SMT-LIB: `zero_extend` (indexed) + * SMT-LIB: `zero_extend` (indexed) */ BITWUZLA_KIND_BV_ZERO_EXTEND(92), /** * Floating-point to_fp from IEEE 754 bit-vector. * - * SMT-LIB: `to_fp` (indexed) + * SMT-LIB: `to_fp` (indexed) */ BITWUZLA_KIND_FP_TO_FP_FROM_BV(93), /** * Floating-point to_fp from floating-point. * - * SMT-LIB: `to_fp` (indexed) + * SMT-LIB: `to_fp` (indexed) */ BITWUZLA_KIND_FP_TO_FP_FROM_FP(94), /** * Floating-point to_fp from signed bit-vector value. * - * SMT-LIB: `to_fp` (indexed) + * SMT-LIB: `to_fp` (indexed) */ BITWUZLA_KIND_FP_TO_FP_FROM_SBV(95), /** * Floating-point to_fp from unsigned bit-vector value. * - * SMT-LIB: `to_fp_unsigned` (indexed) + * SMT-LIB: `to_fp_unsigned` (indexed) */ BITWUZLA_KIND_FP_TO_FP_FROM_UBV(96), /** * Floating-point to_sbv. * - * SMT-LIB: `fp.to_sbv` (indexed) + * SMT-LIB: `fp.to_sbv` (indexed) */ BITWUZLA_KIND_FP_TO_SBV(97), /** * Floating-point to_ubv. * - * SMT-LIB: `fp.to_ubv` (indexed) + * SMT-LIB: `fp.to_ubv` (indexed) */ BITWUZLA_KIND_FP_TO_UBV(98), BITWUZLA_NUM_KINDS(99); diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaOption.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaOption.kt index 56b82a97c..1e83ed620 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaOption.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaOption.kt @@ -1,4 +1,5 @@ @file:Suppress("MagicNumber") + package org.ksmt.solver.bitwuzla.bindings /** @@ -20,7 +21,8 @@ enum class BitwuzlaOption(val value: Int) { /* --------------------------- General Options --------------------------- */ - /** **Configure the solver engine.** + /** + * **Configure the solver engine.** * * Values: * * **aigprop**: @@ -39,7 +41,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_ENGINE(0), - /** **Use non-zero exit codes for sat and unsat results.** + /** + * **Use non-zero exit codes for sat and unsat results.** * * When enabled, use Bitwuzla exit codes: * * [BitwuzlaResult.BITWUZLA_SAT] @@ -55,7 +58,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_EXIT_CODES(1), - /** **Configure input file format.** + /** + * **Configure input file format.** * * If unspecified, Bitwuzla will autodetect the input file format. * @@ -67,7 +71,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_INPUT_FORMAT(2), - /** **Incremental solving.** + /** + * **Incremental solving.** * * Values: * * **1**: enable @@ -81,26 +86,29 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_INCREMENTAL(3), - /** **Log level.** + /** + * **Log level.** * * Values: * * An unsigned integer value (**default**: 0). */ BITWUZLA_OPT_LOGLEVEL(4), - /** **Configure output number format for bit-vector values.** + /** + * **Configure output number format for bit-vector values.** * * If unspecified, Bitwuzla will use BTOR format. * * Values: - * * **aiger**: AIGER ascii format - * * **aigerbin**: AIGER binary format - * * **btor** **(default)**: BTOR format - * * **smt2**: SMT-LIB v2 format + * * **aiger**: AIGER ascii format + * * **aigerbin**: AIGER binary format + * * **btor** **(default)**: BTOR format + * * **smt2**: SMT-LIB v2 format */ BITWUZLA_OPT_OUTPUT_FORMAT(5), - /** **Configure output number format for bit-vector values.** + /** + * **Configure output number format for bit-vector values.** * * If unspecified, Bitwuzla will use binary representation. * @@ -114,7 +122,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_OUTPUT_NUMBER_FORMAT(6), - /** **Pretty printing.** + /** + * **Pretty printing.** * * Values: * * **1**: enable **(default)** @@ -122,7 +131,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PRETTY_PRINT(7), - /** **Print DIMACS.** + /** + * **Print DIMACS.** * * Print the CNF sent to the SAT solver in DIMACS format to stdout. * @@ -132,7 +142,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PRINT_DIMACS(8), - /** **Model generation.** + /** + * **Model generation.** * * Values: * * **1**: enable, generate model for assertions only @@ -143,7 +154,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PRODUCE_MODELS(9), - /** **Unsat core generation.** + /** + * **Unsat core generation.** * * Values: * * **1**: enable @@ -151,7 +163,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PRODUCE_UNSAT_CORES(10), - /** **Configure the SAT solver engine.** + /** + * **Configure the SAT solver engine.** * * Values: * * **cadical** **(default)**: @@ -171,14 +184,16 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SAT_ENGINE(11), - /** **Seed for random number generator.** + /** + * **Seed for random number generator.** * * Values: * * An unsigned integer value (**default**: 0). */ BITWUZLA_OPT_SEED(12), - /** **Verbosity level.** + /** + * **Verbosity level.** * * Values: * * An unsigned integer value <= 4 (**default**: 0). @@ -187,7 +202,8 @@ enum class BitwuzlaOption(val value: Int) { /* -------------- Rewriting/Preprocessing Options (Expert) --------------- */ - /** **Ackermannization preprocessing.** + /** + * **Ackermannization preprocessing.** * * Eager addition of Ackermann constraints for function applications. * @@ -199,7 +215,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PP_ACKERMANN(14), - /** **Beta reduction preprocessing.** + /** + * **Beta reduction preprocessing.** * * Eager elimination of lambda terms via beta reduction. * @@ -215,7 +232,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PP_BETA_REDUCE(15), - /** **Eliminate bit-vector extracts (preprocessing).** + /** + * **Eliminate bit-vector extracts (preprocessing).** * * Values: * * **1**: enable **(default)** @@ -225,7 +243,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PP_ELIMINATE_EXTRACTS(16), - /** **Eliminate ITEs (preprocessing).** + /** + * **Eliminate ITEs (preprocessing).** * * Values: * * **1**: enable @@ -235,7 +254,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PP_ELIMINATE_ITES(17), - /** **Extract lambdas (preprocessing).** + /** + * **Extract lambdas (preprocessing).** * * Extraction of common array patterns as lambda terms. * @@ -247,7 +267,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PP_EXTRACT_LAMBDAS(18), - /** **Merge lambda terms (preprocessing).** + /** + * **Merge lambda terms (preprocessing).** * * Values: * * **1**: enable **(default)** @@ -257,7 +278,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PP_MERGE_LAMBDAS(19), - /** **Non-destructive term substitutions.** + /** + * **Non-destructive term substitutions.** * * Values: * * **1**: enable @@ -267,7 +289,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PP_NONDESTR_SUBST(20), - /** **Normalize bit-vector addition (global).** + /** + * **Normalize bit-vector addition (global).** * * Values: * * **1**: enable **(default)** @@ -277,7 +300,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PP_NORMALIZE_ADD(21), - /** **Boolean skeleton preprocessing.** + /** + * **Boolean skeleton preprocessing.** * * Values: * * **1**: enable **(default)** @@ -287,7 +311,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PP_SKELETON_PREPROC(22), - /** **Unconstrained optimization (preprocessing).** + /** + * **Unconstrained optimization (preprocessing).** * * Values: * * **1**: enable @@ -297,7 +322,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PP_UNCONSTRAINED_OPTIMIZATION(23), - /** **Variable substitution preprocessing.** + /** + * **Variable substitution preprocessing.** * * Values: * * **1**: enable **(default)** @@ -307,7 +333,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PP_VAR_SUBST(24), - /** **Propagate bit-vector extracts over arithmetic bit-vector operators.** + /** + * **Propagate bit-vector extracts over arithmetic bit-vector operators.** * * Values: * * **1**: enable @@ -317,7 +344,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_RW_EXTRACT_ARITH(25), - /** **Rewrite level.** + /** + * **Rewrite level.** * * Values: * * **0**: no rewriting @@ -332,7 +360,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_RW_LEVEL(26), - /** **Normalize bit-vector operations.** + /** + * **Normalize bit-vector operations.** * * Normalize bit-vector addition, multiplication and bit-wise and. * @@ -344,7 +373,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_RW_NORMALIZE(27), - /** **Normalize bit-vector addition (local).** + /** + * **Normalize bit-vector addition (local).** * * Values: * * **1**: enable **(default)** @@ -354,7 +384,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_RW_NORMALIZE_ADD(28), - /** **Simplify constraints on construction.** + /** + * **Simplify constraints on construction.** * * Values: * * **1**: enable **(default)** @@ -364,7 +395,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_RW_SIMPLIFY_CONSTRAINTS(29), - /** **Eliminate bit-vector SLT nodes.** + /** + * **Eliminate bit-vector SLT nodes.** * * Values: * * **1**: enable @@ -374,7 +406,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_RW_SLT(30), - /** **Sort the children of AIG nodes by id.** + /** + * **Sort the children of AIG nodes by id.** * * Values: * * **1**: enable **(default)** @@ -384,7 +417,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_RW_SORT_AIG(31), - /** **Sort the children of adder and multiplier circuits by id.** + /** + * **Sort the children of adder and multiplier circuits by id.** * * Values: * * **1**: enable **(default)** @@ -394,7 +428,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_RW_SORT_AIGVEC(32), - /** **Sort the children of commutative operations by id.** + /** + * **Sort the children of commutative operations by id.** * * Values: * * **1**: enable **(default)** @@ -406,13 +441,8 @@ enum class BitwuzlaOption(val value: Int) { /* --------------------- Fun Engine Options (Expert) --------------------- */ - - - - - - - /** **Function solver engine: + /** + * **Function solver engine: * Dual propagation optimization.** * * Values: @@ -423,7 +453,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_FUN_DUAL_PROP(34), - /** **Function solver engine: + /** + * **Function solver engine: * Assumption order for dual propagation optimization.** * * Set order in which inputs are assumed in the dual propagation clone. @@ -440,7 +471,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_FUN_DUAL_PROP_QSORT(35), - /** **Function solver engine: + /** + * **Function solver engine: * Eager lemmas.** * * Configure mode for eager lemma generation. @@ -459,7 +491,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_FUN_EAGER_LEMMAS(36), - /** **Function solver engine: + /** + * **Function solver engine: * Lazy synthesis.** * * Configure lazy synthesis (to bit-level) of bit-vector expressions. @@ -472,7 +505,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_FUN_LAZY_SYNTHESIZE(37), - /** **Function solver engine: + /** + * **Function solver engine: * Justification optimization.** * * Values: @@ -483,7 +517,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_FUN_JUST(38), - /** **Function solver engine: + /** + * **Function solver engine: * Justification optimization heuristic.** * * Configure heuristic to determine path selection for justification @@ -501,7 +536,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_FUN_JUST_HEURISTIC(39), - /** **Function solver engine: + /** + * **Function solver engine: * Propagation-based local search sequential portfolio.** * * When function solver engine is enabled, configure propagation-based local @@ -516,7 +552,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_FUN_PREPROP(40), - /** **Function solver engine: + /** + * **Function solver engine: * Stochastic local search sequential portfolio.** * * When function solver engine is enabled, configure stochastic local @@ -531,7 +568,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_FUN_PRESLS(41), - /** **Function solver engine: + /** + * **Function solver engine: * Represent store as lambda.** * * Represent array stores as lambdas. @@ -546,13 +584,8 @@ enum class BitwuzlaOption(val value: Int) { /* --------------------- SLS Engine Options (Expert) --------------------- */ - - - - - - - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Justification-based path selection.** * * Configure justification-based path selection for SLS engine. @@ -565,7 +598,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_JUST(43), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Group-wise moves.** * * Configure group-wise moves for SLS engine. When enabled, rather than @@ -580,7 +614,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_MOVE_GW(44), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Incremental move test.** * * Configure that during best move selection, the previous best neighbor @@ -595,7 +630,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_MOVE_INC_MOVE_TEST(45), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Propagation moves.** * * Configure propagation moves, chosen with a ratio of number of propagation @@ -610,7 +646,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_MOVE_PROP(46), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Force random walks.** * * Configure that random walks are forcibly chosen as recovery moves in case @@ -625,7 +662,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_MOVE_PROP_FORCE_RW(47), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Number of propagation moves.** * * Configure the number of propagation moves to be performed when propagation @@ -643,7 +681,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_MOVE_PROP_NPROPS(48), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Number of regular SLS moves.** * * Configure the number of regular SLS moves to be performed when propagation @@ -661,7 +700,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_MOVE_PROP_NSLSS(49), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Randomize all candidates.** * * Configure the randomization of all candidate variables (rather than just @@ -675,7 +715,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_MOVE_RAND_ALL(50), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Randomize bit ranges.** * * Configure the randomization of bit ranges (rather than all bits) of @@ -689,7 +730,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_MOVE_RAND_RANGE(51), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Random walk.** * * Configure random walk moves, where one out of all possible neighbors is @@ -707,7 +749,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_MOVE_RAND_WALK(52), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Range-wise bit-flip moves.** * * Configure range-wise bit-flip moves for SLS engine. When enabled, try @@ -722,7 +765,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_MOVE_RANGE(53), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Segment-wise bit-flip moves.** * * Configure range-wise bit-flip moves for SLS engine. When enabled, try @@ -737,7 +781,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_MOVE_SEGMENT(54), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Probability for random walks.** * * Configure the probability with which a random walk is chosen if random @@ -752,7 +797,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_PROB_MOVE_RAND_WALK(55), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Number of bit flips.** * * Configure the number of bit flips used as a limit for the SLS engine. @@ -764,7 +810,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_NFLIPS(56), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Move strategy.** * * Configure the move selection strategy for the SLS engine. @@ -786,7 +833,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_STRATEGY(57), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Restarts.** * * Values: @@ -797,7 +845,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SLS_USE_RESTARTS(58), - /** **Stochastic local search solver engine: + /** + * **Stochastic local search solver engine: * Bandit scheme.** * * Configure bandit scheme heuristic for selecting root constraints. @@ -813,7 +862,8 @@ enum class BitwuzlaOption(val value: Int) { /* -------------------- Prop Engine Options (Expert) --------------------- */ - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Value computation for xor.** * * When enabled, detect arithmetic right shift operations (are rewritten on @@ -827,7 +877,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_ASHR(60), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Constant bits.** * * Configure constant bit propagation (requries bit-blasting to AIG). @@ -840,7 +891,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_CONST_BITS(61), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Domain propagators.** * * Configure the use of domain propagators for determining constant bits @@ -854,7 +906,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_CONST_DOMAINS(62), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Entailed propagations.** * * Maintain a work queue with entailed propagations. @@ -876,7 +929,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_ENTAILED(63), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Delta for flipping ite conditions with constant branches.** * * Configure the delta by which [BITWUZLA_OPT_PROP_PROB_FLIP_COND_CONST] is @@ -890,7 +944,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_FLIP_COND_CONST_DELTA(64), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Limit for flipping ite conditions with constant branches.** * * Configure the limit for how often the path to the condition for ite @@ -905,7 +960,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_FLIP_COND_CONST_NPATHSEL(65), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Infer bounds for inequalities for value computation.** * * When enabled, infer bounds for value computation for inequalities based on @@ -919,7 +975,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_INFER_INEQ_BOUNDS(66), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * No move on conflict.** * * When enabled, no move is performed when running into a conflict during @@ -937,7 +994,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_NO_MOVE_ON_CONFLICT(67), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Number of propagations.** * * Configure the number of propagations used as a limit for the @@ -950,7 +1008,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_NPROPS(68), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Number of updates.** * * Configure the number of model value updates used as a limit for the @@ -963,7 +1022,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_NUPDATES(69), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Path selection.** * * Configure mode for path selection. @@ -978,7 +1038,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_PATH_SEL(70), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Probability for producing inverse rather than consistent values.** * * Values: @@ -988,7 +1049,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_PROB_FALLBACK_RANDOM_VALUE(71), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Probability for flipping one of the don't care bits for ands.** * * Configure the probability with which to keep the current assignement of @@ -1003,7 +1065,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_PROB_AND_FLIP(72), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Probability for using the current assignment with one bit flipped for * equalities.** * @@ -1018,7 +1081,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_PROB_EQ_FLIP(73), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Probability for flipping ite condition.** * * Configure the probability with which to select the path to the condition @@ -1032,7 +1096,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_PROB_FLIP_COND(74), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Probability for flipping ite condition with constant branches.** * * Configure the probability with which to select the path to the condition @@ -1046,7 +1111,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_PROB_FLIP_COND_CONST(75), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Probability for selecting random input.** * * Configure the probability with which to select a random input instead of @@ -1059,7 +1125,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_PROB_RANDOM_INPUT(76), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Probability for flipping one of the don't care bits for extracts.** * * Configure the probability with which to flip one of the don't care bits of @@ -1075,7 +1142,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_PROB_SLICE_FLIP(77), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Probability for keeping the value of don't care bits for extracts.** * * Configure the probability with which to keep the current value of don't @@ -1089,7 +1157,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_PROB_SLICE_KEEP_DC(78), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Probability for inverse values.** * * Configure the probability with which to choose an inverse value over a @@ -1102,7 +1171,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_PROB_USE_INV_VALUE(79), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Bandit scheme.** * * Configure bandit scheme heuristic for selecting root constraints. @@ -1118,7 +1188,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_USE_BANDIT(80), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Inverse value computation for inequalities over concats.** * * When enabled, use special inverse value computation for inequality over @@ -1132,7 +1203,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_USE_INV_LT_CONCAT(81), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Restarts.** * * Values: @@ -1143,7 +1215,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_USE_RESTARTS(82), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Value computation for sign extension.** * * When enabled, detect sign extension operations (are rewritten on @@ -1157,7 +1230,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_SEXT(83), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Skip if no progress.** * * When enabled, moves that make no progress, that is, that produce a target @@ -1172,7 +1246,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PROP_SKIP_NO_PROGRESS(84), - /** **Propagation-based local search solver engine: + /** + * **Propagation-based local search solver engine: * Value computation for xor.** * * When enabled, detect xor operations (are rewritten on construction) and @@ -1188,7 +1263,8 @@ enum class BitwuzlaOption(val value: Int) { /* ------------------- AigProp Engine Options (Expert) ------------------- */ - /** **AIG-level propagation-based local search solver engine: + /** + * **AIG-level propagation-based local search solver engine: * Number of propagations.** * * Configure the number of propagations used as a limit for the @@ -1201,7 +1277,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_AIGPROP_NPROPS(86), - /** **AIG-level propagation-based local search solver engine: + /** + * **AIG-level propagation-based local search solver engine: * Bandit scheme.** * * Configure bandit scheme heuristic for selecting root constraints. @@ -1217,7 +1294,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_AIGPROP_USE_BANDIT(87), - /** **AIG-level propagation-based local search solver engine: + /** + * **AIG-level propagation-based local search solver engine: * Restarts.** * * Values: @@ -1230,7 +1308,8 @@ enum class BitwuzlaOption(val value: Int) { /* ----------------- Quantifier Eninge Options (Expert) ------------------ */ - /** **Quantifier solver engine: + /** + * **Quantifier solver engine: * Constructive Equality Resolution.** * * Configure the use of Constructive Equality Resolution simplification in @@ -1245,7 +1324,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_QUANT_CER(89), - /** **Quantifier solver engine: + /** + * **Quantifier solver engine: * Destructive Equality Resolution.** * * Configure the use of Destructive Equality Resolution simplification in @@ -1260,7 +1340,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_QUANT_DER(90), - /** **Quantifier solver engine: + /** + * **Quantifier solver engine: * Dual solver.** * * Configure the use of the dual (negated) version of the quantified formula. @@ -1274,7 +1355,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_QUANT_DUAL_SOLVER(91), - /** **Quantifier solver engine: + /** + * **Quantifier solver engine: * Miniscoping.** * * Configure the use of miniscoping in the quantifier solver engine. @@ -1288,7 +1370,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_QUANT_MINISCOPE(92), - /** **Quantifier solver engine: + /** + * **Quantifier solver engine: * Synthesis mode.** * * Configure mode for synthesizing Skolem functions. @@ -1312,7 +1395,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_QUANT_SYNTH(93), - /** **Quantifier solver engine: + /** + * **Quantifier solver engine: * Update model with respect to synthesized skolem.** * * Configure to update the current model with respect to the synthesized @@ -1327,7 +1411,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_QUANT_FIXSYNTH(94), - /** **Quantifier solver engine: + /** + * **Quantifier solver engine: * Base case for ITE model.** * * Configure the base case of a concrete model for ITEs. Constant if enabled, @@ -1342,7 +1427,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_QUANT_SYNTH_ITE_COMPLETE(95), - /** **Quantifier solver engine: + /** + * **Quantifier solver engine: * Limit for synthesis.** * * Configure the limit of enumerated expressions for the enumerative learning @@ -1356,7 +1442,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_QUANT_SYNTH_LIMIT(96), - /** **Quantifier solver engine: + /** + * **Quantifier solver engine: * Quantifier instantiation.** * * Configure the generalization of quantifier instantiations via enumerative @@ -1373,7 +1460,8 @@ enum class BitwuzlaOption(val value: Int) { /* ------------------------ Other Expert Options ------------------------- */ - /** **Check model (debug only).** + /** + * **Check model (debug only).** * * Values: * * **1**: enable **(default)** @@ -1383,7 +1471,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_CHECK_MODEL(98), - /** **Check result when unconstrained optimization is enabled (debug only).** + /** + * **Check result when unconstrained optimization is enabled (debug only).** * * Values: * * **1**: enable **(default)** @@ -1393,7 +1482,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_CHECK_UNCONSTRAINED(99), - /** **Check unsat assumptions (debug only).** + /** + * **Check unsat assumptions (debug only).** * * Values: * * **1**: enable **(default)** @@ -1403,7 +1493,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_CHECK_UNSAT_ASSUMPTIONS(100), - /** **Interpret sorts introduced with declare-sort as bit-vectors of given + /** + * **Interpret sorts introduced with declare-sort as bit-vectors of given * width.** * * Disabled if zero. @@ -1415,7 +1506,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_DECLSORT_BV_WIDTH(101), - /** **Share partial models determined via local search with bit-blasting + /** + * **Share partial models determined via local search with bit-blasting * engine.** * * This option is only effective when local search engines are combined with @@ -1429,7 +1521,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_LS_SHARE_SAT(102), - /** **Interactive parsing mode.** + /** + * **Interactive parsing mode.** * * Values: * * **1**: enable **(default)** @@ -1439,7 +1532,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_PARSE_INTERACTIVE(103), - /** **Use CaDiCaL's freeze/melt.** + /** + * **Use CaDiCaL's freeze/melt.** * * Values: * * **1**: enable @@ -1449,7 +1543,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SAT_ENGINE_CADICAL_FREEZE(104), - /** **Lingeling fork mode.** + /** + * **Lingeling fork mode.** * * Values: * * **1**: enable **(default)** @@ -1459,7 +1554,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SAT_ENGINE_LGL_FORK(105), - /** **Number of threads to use in the SAT solver.** + /** + * **Number of threads to use in the SAT solver.** * * This option is only effective for SAT solvers with support for * multi-threading. @@ -1471,7 +1567,8 @@ enum class BitwuzlaOption(val value: Int) { */ BITWUZLA_OPT_SAT_ENGINE_N_THREADS(106), - /** **Enable SMT-COMP mode.** + /** + * **Enable SMT-COMP mode.** * * Parser only option. Only effective when an SMT2 input file is parsed. * diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaResult.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaResult.kt index db7fec7af..22609a5f1 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaResult.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaResult.kt @@ -1,4 +1,5 @@ @file:Suppress("MagicNumber") + package org.ksmt.solver.bitwuzla.bindings /** diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaRoundingMode.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaRoundingMode.kt index d76925f05..b5d50b57d 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaRoundingMode.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/BitwuzlaRoundingMode.kt @@ -1,13 +1,14 @@ @file:Suppress("MagicNumber") + package org.ksmt.solver.bitwuzla.bindings /** * Rounding mode for floating-point operations. - * + * * For some floating-point operations, infinitely precise results may not be * representable in a given format. Hence, they are rounded modulo one of five * rounding modes to a representable floating-point number. - * + * * The following rounding modes follow the SMT-LIB theory for floating-point * arithmetic, which in turn is based on IEEE Standard 754. * The rounding modes are specified in Sections 4.3.1 and 4.3.2 of the IEEE Standard 754. @@ -19,7 +20,7 @@ enum class BitwuzlaRoundingMode(val value: Int) { * If the two nearest floating-point numbers bracketing an unrepresentable * infinitely precise result are equally near, the one with an even least * significant digit will be delivered. - * + * * SMT-LIB: `RNE` `roundNearestTiesToEven` */ BITWUZLA_RM_RNE(0), diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/FilePtrUtils.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/FilePtrUtils.kt index f998e6748..01f118a65 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/FilePtrUtils.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/FilePtrUtils.kt @@ -46,15 +46,15 @@ object FilePtrUtils { } private val stdout: FilePtr by lazy { - FilePtr(lib.fdopen(1, "w"), closable = false) + FilePtr(lib.fdopen(1, "w"), isClosable = false) } } -class FilePtr internal constructor(val ptr: Pointer, private val closable: Boolean = true) : AutoCloseable { +class FilePtr internal constructor(val ptr: Pointer, private val isClosable: Boolean = true) : AutoCloseable { override fun close() { FilePtrUtils.flush(this) - if (closable) { + if (isClosable) { FilePtrUtils.close(this) } } diff --git a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/Native.kt b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/Native.kt index be9ab0f14..2633e78d6 100644 --- a/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/Native.kt +++ b/ksmt-bitwuzla/src/main/kotlin/org/ksmt/solver/bitwuzla/bindings/Native.kt @@ -70,7 +70,7 @@ object Native { * This deletes the given instance and creates a new instance in place. * The given instance must have been created via [bitwuzla_new]. * - * Note: All sorts and terms associated with the given instance are released + * Note: All sorts and terms associated with the given instance are released * and thus invalidated. * * @param bitwuzla The Bitwuzla instance to reset. @@ -198,7 +198,7 @@ object Native { * Configure an abort callback function, which is called instead of exit * on abort conditions. * - * Note: This function is not thread safe (the function pointer is maintained + * Note: This function is not thread safe (the function pointer is maintained * as a global variable). It you use threading, make sure to set the * abort callback prior to creating threads. * @@ -332,7 +332,7 @@ object Native { /** * Create a Boolean sort. * - * Note: A Boolean sort is a bit-vector sort of size 1. + * Note: A Boolean sort is a bit-vector sort of size 1. * * @param bitwuzla The Bitwuzla instance. * @@ -438,7 +438,7 @@ object Native { /** * Create a true value. * - * Note: This creates a bit-vector value 1 of size 1. + * Note: This creates a bit-vector value 1 of size 1. * * @param bitwuzla The Bitwuzla instance. * @@ -453,7 +453,7 @@ object Native { /** * Create a false value. * - * Note: This creates a bit-vector value 0 of size 1. + * Note: This creates a bit-vector value 0 of size 1. * * @param bitwuzla The Bitwuzla instance. * @@ -638,7 +638,7 @@ object Native { * * Parameter `base` determines the base of the string representation. * - * Note: Given value must fit into a bit-vector of given size (sort). + * Note: Given value must fit into a bit-vector of given size (sort). * * @param bitwuzla The Bitwuzla instance. * @param sort The sort of the value. @@ -669,7 +669,7 @@ object Native { /** * Create a bit-vector value from its unsigned integer representation. * - * Note: If given value does not fit into a bit-vector of given size (sort), + * Note: If given value does not fit into a bit-vector of given size (sort), * the value is truncated to fit. * * @param bitwuzla The Bitwuzla instance. @@ -1082,7 +1082,7 @@ object Native { /** * Create a variable of given sort with given symbol. * - * Note: This creates a variable to be bound by quantifiers or lambdas. + * Note: This creates a variable to be bound by quantifiers or lambdas. * * @param bitwuzla The Bitwuzla instance. * @param sort The sort of the variable. @@ -1108,7 +1108,7 @@ object Native { * Requires that incremental solving has been enabled via * [bitwuzla_set_option]. * - * Note: Assumptions added via this [bitwuzla_assume] are not affected by + * Note: Assumptions added via this [bitwuzla_assume] are not affected by * context level changes and are only valid until the next * [bitwuzla_check_sat] call, no matter at which level they were * assumed. @@ -1131,7 +1131,7 @@ object Native { * Requires that incremental solving has been enabled via * [bitwuzla_set_option]. * - * Note: Assumptions added via this [bitwuzla_assume] are not affected by + * Note: Assumptions added via this [bitwuzla_assume] are not affected by * context level changes and are only valid until the next * [bitwuzla_check_sat] call, no matter at which level they were * assumed. @@ -1166,7 +1166,7 @@ object Native { * Requires that incremental solving has been enabled via * [bitwuzla_set_option]. * - * Note: Assumptions added via this function are not affected by context level + * Note: Assumptions added via this function are not affected by context level * changes and are only valid until the next [bitwuzla_check_sat] call, * no matter at which level they were assumed. * @@ -1238,6 +1238,7 @@ object Native { fun bitwuzlaGetUnsatAssumptions(bitwuzla: Bitwuzla): Array { val size = IntByReference() val resultPtr = bitwuzla_get_unsat_assumptions(bitwuzla, size).checkError() + return resultPtr.load(size.value) } @@ -1298,7 +1299,7 @@ object Native { /** * Simplify the current input formula. * - * Note: Assumptions are not considered for simplification. + * Note: Assumptions are not considered for simplification. * * @param bitwuzla The Bitwuzla instance. * @@ -1322,7 +1323,7 @@ object Native { * The search for a solution can by guided by making assumptions via * [bitwuzla_assume]. * - * Note: Assertions and assumptions are combined via Boolean and. Multiple + * Note: Assertions and assumptions are combined via Boolean and. Multiple * calls to this function require enabling incremental solving via * [bitwuzla_set_option]. * @@ -1395,7 +1396,9 @@ object Native { val exponentPtr = PointerByReference() val significandPtr = PointerByReference() bitwuzla_get_fp_value(bitwuzla, term, signPtr, exponentPtr, significandPtr) + checkError() + return FpValue( signPtr.value.getString(0), exponentPtr.value.getString(0), @@ -1455,6 +1458,7 @@ object Native { bitwuzla_get_array_value(bitwuzla, term, indices, values, size, defaultValue) checkError() val sz = size.value + return ArrayValue( sz, indices.value.load(sz), @@ -1683,9 +1687,12 @@ object Native { val parsedStatus = IntByReference() val result = bitwuzla_parse_format( bitwuzla, format, infile.ptr, infileName, outfile.ptr, errorMsg, parsedStatus - ).checkError() + ) + result.checkError() + infile.close() outfile.close() + return ParseFormatResult( BitwuzlaResult.fromValue(result), errorMsg.value?.let { if (Pointer.NULL == it) null else it.getString(0) }, @@ -1734,8 +1741,13 @@ object Native { term: BitwuzlaTerm, mapKeys: Array, mapValues: Array - ): BitwuzlaTerm = bitwuzla_substitute_term(bitwuzla, term, mapKeys.size, mapKeys.mkPtr(), mapValues.mkPtr()) - .checkError() + ): BitwuzlaTerm = bitwuzla_substitute_term( + bitwuzla, + term, + mapKeys.size, + mapKeys.mkPtr(), + mapValues.mkPtr() + ).checkError() private external fun bitwuzla_substitute_term( bitwuzla: Bitwuzla, @@ -1767,8 +1779,11 @@ object Native { ) { val termsPtr = terms.mkPtr() bitwuzla_substitute_terms(bitwuzla, terms.size, termsPtr, mapKeys.size, mapKeys.mkPtr(), mapValues.mkPtr()) + checkError() + val result = termsPtr.load(terms.size) + for (i in terms.indices) { terms[i] = result[i] } @@ -2729,14 +2744,17 @@ object Native { private fun Array.mkPtr(): Pointer { val memory = Memory(Native.POINTER_SIZE.toLong() * size) + for (i in indices) { memory.setPointer(Native.POINTER_SIZE.toLong() * i, this[i]) } + return memory } private fun Pointer?.load(size: Int): Array { if (this == null || Pointer.NULL == this || size == 0) return emptyArray() + return getPointerArray(0, size) } @@ -2744,11 +2762,12 @@ object Native { private fun T.checkError(): T { val pendingError = error + if (pendingError != null) { error = null throw BitwuzlaException(pendingError) } + return this } - } diff --git a/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/BenchmarksBasedTest.kt b/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/BenchmarksBasedTest.kt index d6d12883e..7d73fab18 100644 --- a/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/BenchmarksBasedTest.kt +++ b/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/BenchmarksBasedTest.kt @@ -111,6 +111,7 @@ class BenchmarksBasedTest { it as KExpr eq model.eval(it) } } + KZ3Solver(ctx).use { z3Solver -> ksmtAssertions.forEach { z3Solver.assert(it) } modelAssignments.forEach { z3Solver.assert(it) } @@ -175,6 +176,7 @@ class BenchmarksBasedTest { solver.pop() if (status == KSolverStatus.SAT) return check } + return null } } diff --git a/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/ConverterTest.kt b/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/ConverterTest.kt index a36e908bd..59d51bcb2 100644 --- a/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/ConverterTest.kt +++ b/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/ConverterTest.kt @@ -3,7 +3,7 @@ package org.ksmt.solver.bitwuzla import org.ksmt.KContext import org.ksmt.expr.KApp import org.ksmt.expr.KExpr -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KNonRecursiveTransformer import org.ksmt.solver.bitwuzla.bindings.BitwuzlaKind import org.ksmt.solver.bitwuzla.bindings.BitwuzlaOption import org.ksmt.solver.bitwuzla.bindings.BitwuzlaResult @@ -143,7 +143,7 @@ class ConverterTest { mkIte(this@toBool eq mkBv(true), trueExpr, falseExpr) } - private class SortChecker(override val ctx: KContext) : KTransformer { + private class SortChecker(ctx: KContext) : KNonRecursiveTransformer(ctx) { override fun transformApp(expr: KApp): KExpr = with(ctx) { // apply internally check arguments sorts expr.decl.apply(expr.args) diff --git a/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/Example.kt b/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/Example.kt index 59c6224e8..4676402fb 100644 --- a/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/Example.kt +++ b/ksmt-bitwuzla/src/test/kotlin/org/ksmt/solver/bitwuzla/Example.kt @@ -16,37 +16,53 @@ class Example { @Suppress("USELESS_IS_CHECK") fun test() = with(KContext()) { val a = boolSort.mkConst("a") + val b = mkFuncDecl("b", boolSort, listOf(boolSort)) val xFun = mkFuncDecl("xFun", boolSort, listOf(boolSort, boolSort, boolSort)) + val c = boolSort.mkConst("c") + val e = mkArraySort(boolSort, boolSort).mkConst("e") val eConst = mkArraySort(boolSort, boolSort).mkConst("eConst") val solver = KBitwuzlaSolver(this) - solver.assert(a) - solver.assert(b.apply(listOf(trueExpr)) eq falseExpr) - solver.assert(xFun.apply(listOf(trueExpr, trueExpr, trueExpr)) eq falseExpr) - solver.assert(xFun.apply(listOf(trueExpr, falseExpr, trueExpr)) eq falseExpr) - solver.assert(xFun.apply(listOf(falseExpr, falseExpr, trueExpr)) eq trueExpr) - solver.assert(e.select(a) eq trueExpr) - solver.assert(e.select(trueExpr) eq trueExpr) - solver.assert(e.select(falseExpr) eq falseExpr) - solver.assert(eConst eq mkArrayConst(mkArraySort(boolSort, boolSort), trueExpr)) + + with(solver) { + assert(a) + assert(b.apply(listOf(trueExpr)) eq falseExpr) + assert(xFun.apply(listOf(trueExpr, trueExpr, trueExpr)) eq falseExpr) + assert(xFun.apply(listOf(trueExpr, falseExpr, trueExpr)) eq falseExpr) + assert(xFun.apply(listOf(falseExpr, falseExpr, trueExpr)) eq trueExpr) + assert(e.select(a) eq trueExpr) + assert(e.select(trueExpr) eq trueExpr) + assert(e.select(falseExpr) eq falseExpr) + assert(eConst eq mkArrayConst(mkArraySort(boolSort, boolSort), trueExpr)) + } + val status = solver.check() + assertEquals(status, KSolverStatus.SAT) + val model = solver.model() val aValue = model.eval(a) val cValue = model.eval(c) val eValue = model.eval(e) + assertEquals(aValue, trueExpr) assertTrue(eValue.sort is KArraySort<*, *>) + val bInterp = model.interpretation(b) + model.interpretation(xFun) model.interpretation(e.decl) model.interpretation(a.decl) model.interpretation(eConst.decl) + assertNotNull(bInterp) + val detachedModel = model.detach() + solver.close() + assertFailsWith(IllegalStateException::class) { model.eval(a) } assertEquals(aValue, detachedModel.eval(a)) assertEquals(cValue, detachedModel.eval(c)) diff --git a/ksmt-core/src/main/kotlin/example/Example.kt b/ksmt-core/src/main/kotlin/example/Example.kt index 33d3d1b5e..bb717205d 100644 --- a/ksmt-core/src/main/kotlin/example/Example.kt +++ b/ksmt-core/src/main/kotlin/example/Example.kt @@ -16,7 +16,6 @@ fun main() = with(KContext()) { val bv8 = mkBv(0.toByte()) val byteBits = Byte.SIZE_BITS - // how to restrict such casts to avoid misscast? For example, you can write `as KBitVec16Expr` as well val sameBv8 = mkBv("0".repeat(byteBits), byteBits.toUInt()) as KBitVec8Value check(bv8 === sameBv8) diff --git a/ksmt-core/src/main/kotlin/org/ksmt/KAst.kt b/ksmt-core/src/main/kotlin/org/ksmt/KAst.kt index 968aaeed0..dd5e3f47a 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/KAst.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/KAst.kt @@ -2,5 +2,6 @@ package org.ksmt abstract class KAst(val ctx: KContext) { abstract fun print(builder: StringBuilder) + override fun toString(): String = with(ctx) { stringRepr } } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/KContext.kt b/ksmt-core/src/main/kotlin/org/ksmt/KContext.kt index 3464840d7..a834c777f 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/KContext.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/KContext.kt @@ -438,7 +438,10 @@ open class KContext : AutoCloseable { KImpliesExpr(this, p, q) } - fun mkImplies(p: KExpr, q: KExpr): KImpliesExpr = impliesCache.createIfContextActive(p, q) + fun mkImplies( + p: KExpr, + q: KExpr + ): KImpliesExpr = impliesCache.createIfContextActive(p, q) private val xorCache = mkContextCheckingCache { a: KExpr, b: KExpr -> KXorExpr(this, a, b) @@ -470,9 +473,16 @@ open class KContext : AutoCloseable { KIteExpr(this, c, t, f) } - fun mkIte(condition: KExpr, trueBranch: KExpr, falseBranch: KExpr): KIteExpr = - iteCache.createIfContextActive(condition, trueBranch.cast(), falseBranch.cast()).cast() + fun mkIte( + condition: KExpr, + trueBranch: KExpr, + falseBranch: KExpr + ): KIteExpr { + val trueArg: KExpr = trueBranch.cast() + val falseArg: KExpr = falseBranch.cast() + return iteCache.createIfContextActive(condition, trueArg, falseArg).cast() + } infix fun KExpr.eq(other: KExpr) = mkEq(this, other) operator fun KExpr.not() = mkNot(this) @@ -518,33 +528,49 @@ open class KContext : AutoCloseable { fun T.mkFreshConst(name: String): KApp = with(mkFreshConstDecl(name)) { apply() } - inline operator fun T.getValue(thisRef: Any?, property: KProperty<*>): KApp = - mkConst(property.name) + inline operator fun T.getValue( + thisRef: Any?, + property: KProperty<*> + ): KApp = mkConst(property.name) // array - private val arrayStoreCache = - mkContextCheckingCache { a: KExpr>, i: KExpr, v: KExpr -> - KArrayStore(this, a, i, v) - } + private val arrayStoreCache = mkContextCheckingCache { a: KExpr>, + i: KExpr, + v: KExpr -> + KArrayStore(this, a, i, v) + } fun mkArrayStore( - array: KExpr>, index: KExpr, value: KExpr - ): KArrayStore = arrayStoreCache.createIfContextActive(array.cast(), index.cast(), value.cast()).cast() + array: KExpr>, + index: KExpr, + value: KExpr + ): KArrayStore { + val arrayArg: KExpr> = array.cast() + val indexArg: KExpr = index.cast() + val valueArg: KExpr = value.cast() - private val arraySelectCache = - mkContextCheckingCache { array: KExpr>, index: KExpr -> - KArraySelect(this, array, index) - } + return arrayStoreCache.createIfContextActive(arrayArg, indexArg, valueArg).cast() + } + + private val arraySelectCache = mkContextCheckingCache { array: KExpr>, + index: KExpr -> + KArraySelect(this, array, index) + } - fun mkArraySelect(array: KExpr>, index: KExpr): KArraySelect = - arraySelectCache.createIfContextActive(array.cast(), index.cast()).cast() + fun mkArraySelect( + array: KExpr>, + index: KExpr + ): KArraySelect = arraySelectCache.createIfContextActive(array.cast(), index.cast()).cast() - private val arrayConstCache = mkContextCheckingCache { array: KArraySort, value: KExpr -> + private val arrayConstCache = mkContextCheckingCache { array: KArraySort, + value: KExpr -> KArrayConst(this, array, value) } - fun mkArrayConst(arraySort: KArraySort, value: KExpr): KArrayConst = - arrayConstCache.createIfContextActive(arraySort.cast(), value.cast()).cast() + fun mkArrayConst( + arraySort: KArraySort, + value: KExpr + ): KArrayConst = arrayConstCache.createIfContextActive(arraySort.cast(), value.cast()).cast() private val functionAsArrayCache = mkContextCheckingCache { function: KFuncDecl -> KFunctionAsArray(this, function) @@ -603,42 +629,48 @@ open class KContext : AutoCloseable { fun > mkArithUnaryMinus(arg: KExpr): KUnaryMinusArithExpr = arithUnaryMinusCache.createIfContextActive(arg.cast()).cast() - private val arithDivCache = mkContextCheckingCache { l: KExpr>, r: KExpr> -> + private val arithDivCache = mkContextCheckingCache { l: KExpr>, + r: KExpr> -> KDivArithExpr(this, l, r) } fun > mkArithDiv(lhs: KExpr, rhs: KExpr): KDivArithExpr = arithDivCache.createIfContextActive(lhs.cast(), rhs.cast()).cast() - private val arithPowerCache = mkContextCheckingCache { l: KExpr>, r: KExpr> -> + private val arithPowerCache = mkContextCheckingCache { l: KExpr>, + r: KExpr> -> KPowerArithExpr(this, l, r) } fun > mkArithPower(lhs: KExpr, rhs: KExpr): KPowerArithExpr = arithPowerCache.createIfContextActive(lhs.cast(), rhs.cast()).cast() - private val arithLtCache = mkContextCheckingCache { l: KExpr>, r: KExpr> -> + private val arithLtCache = mkContextCheckingCache { l: KExpr>, + r: KExpr> -> KLtArithExpr(this, l, r) } fun > mkArithLt(lhs: KExpr, rhs: KExpr): KLtArithExpr = arithLtCache.createIfContextActive(lhs.cast(), rhs.cast()).cast() - private val arithLeCache = mkContextCheckingCache { l: KExpr>, r: KExpr> -> + private val arithLeCache = mkContextCheckingCache { l: KExpr>, + r: KExpr> -> KLeArithExpr(this, l, r) } fun > mkArithLe(lhs: KExpr, rhs: KExpr): KLeArithExpr = arithLeCache.createIfContextActive(lhs.cast(), rhs.cast()).cast() - private val arithGtCache = mkContextCheckingCache { l: KExpr>, r: KExpr> -> + private val arithGtCache = mkContextCheckingCache { l: KExpr>, + r: KExpr> -> KGtArithExpr(this, l, r) } fun > mkArithGt(lhs: KExpr, rhs: KExpr): KGtArithExpr = arithGtCache.createIfContextActive(lhs.cast(), rhs.cast()).cast() - private val arithGeCache = mkContextCheckingCache { l: KExpr>, r: KExpr> -> + private val arithGeCache = mkContextCheckingCache { l: KExpr>, + r: KExpr> -> KGeArithExpr(this, l, r) } @@ -658,17 +690,25 @@ open class KContext : AutoCloseable { infix fun > KExpr.ge(other: KExpr) = mkArithGe(this, other) // integer - private val intModCache = mkContextCheckingCache { l: KExpr, r: KExpr -> + private val intModCache = mkContextCheckingCache { l: KExpr, + r: KExpr -> KModIntExpr(this, l, r) } - fun mkIntMod(lhs: KExpr, rhs: KExpr): KModIntExpr = intModCache.createIfContextActive(lhs, rhs) + fun mkIntMod( + lhs: KExpr, + rhs: KExpr + ): KModIntExpr = intModCache.createIfContextActive(lhs, rhs) - private val intRemCache = mkContextCheckingCache { l: KExpr, r: KExpr -> + private val intRemCache = mkContextCheckingCache { l: KExpr, + r: KExpr -> KRemIntExpr(this, l, r) } - fun mkIntRem(lhs: KExpr, rhs: KExpr): KRemIntExpr = intRemCache.createIfContextActive(lhs, rhs) + fun mkIntRem( + lhs: KExpr, + rhs: KExpr + ): KRemIntExpr = intRemCache.createIfContextActive(lhs, rhs) private val intToRealCache = mkContextCheckingCache { arg: KExpr -> KToRealIntExpr(this, arg) @@ -694,12 +734,15 @@ open class KContext : AutoCloseable { fun mkIntNum(value: BigInteger): KIntBigNumExpr = intBigNumCache.createIfContextActive(value) fun mkIntNum(value: String) = - value.toIntOrNull()?.let { mkIntNum(it) } ?: value.toLongOrNull()?.let { mkIntNum(it) } - ?: mkIntNum(value.toBigInteger()) + value.toIntOrNull() + ?.let { mkIntNum(it) } + ?: value.toLongOrNull()?.let { mkIntNum(it) } + ?: mkIntNum(value.toBigInteger()) infix fun KExpr.mod(rhs: KExpr) = mkIntMod(this, rhs) infix fun KExpr.rem(rhs: KExpr) = mkIntRem(this, rhs) fun KExpr.toRealExpr() = mkIntToReal(this) + val Int.intExpr get() = mkIntNum(this) val Long.intExpr @@ -720,7 +763,8 @@ open class KContext : AutoCloseable { fun mkRealIsInt(arg: KExpr): KIsIntRealExpr = realIsIntCache.createIfContextActive(arg) - private val realNumCache = mkContextCheckingCache { numerator: KIntNumExpr, denominator: KIntNumExpr -> + private val realNumCache = mkContextCheckingCache { numerator: KIntNumExpr, + denominator: KIntNumExpr -> KRealNumExpr(this, numerator, denominator) } @@ -735,6 +779,7 @@ open class KContext : AutoCloseable { fun mkRealNum(numerator: Long, denominator: Long) = mkRealNum(mkIntNum(numerator), mkIntNum(denominator)) fun mkRealNum(value: String): KRealNumExpr { val parts = value.split('/') + return when (parts.size) { 1 -> mkRealNum(mkIntNum(parts[0])) 2 -> mkRealNum(mkIntNum(parts[0]), mkIntNum(parts[1])) @@ -751,10 +796,16 @@ open class KContext : AutoCloseable { private val bv16Cache = mkClosableCache { value: Short -> KBitVec16Value(this, value) } private val bv32Cache = mkClosableCache { value: Int -> KBitVec32Value(this, value) } private val bv64Cache = mkClosableCache { value: Long -> KBitVec64Value(this, value) } - private val bvCache = mkClosableCache { value: String, sizeBits: UInt -> KBitVecCustomValue(this, value, sizeBits) } + private val bvCache = mkClosableCache { value: String, sizeBits: UInt -> + KBitVecCustomValue(this, value, sizeBits) + } fun mkBv(value: Boolean): KBitVec1Value = bv1Cache.createIfContextActive(value) - fun mkBv(value: Boolean, sizeBits: UInt): KBitVecValue = mkBv((if (value) 1 else 0) as Number, sizeBits) + fun mkBv(value: Boolean, sizeBits: UInt): KBitVecValue { + val intValue = (if (value) 1 else 0) as Number + return mkBv(intValue, sizeBits) + } + fun Boolean.toBv(): KBitVec1Value = mkBv(this) fun Boolean.toBv(sizeBits: UInt): KBitVecValue = mkBv(this, sizeBits) @@ -814,220 +865,311 @@ open class KContext : AutoCloseable { fun mkBvNotExpr(value: KExpr): KBvNotExpr = bvNotExprCache.createIfContextActive(value.cast()).cast() - private val bvRedAndExprCache = mkClosableCache { value: KExpr -> KBvReductionAndExpr(this, value) } + private val bvRedAndExprCache = mkClosableCache { value: KExpr -> + KBvReductionAndExpr(this, value) + } fun mkBvReductionAndExpr(value: KExpr): KBvReductionAndExpr = bvRedAndExprCache.createIfContextActive(value.cast()).cast() fun KExpr.reductionAnd(): KBvReductionAndExpr = mkBvReductionAndExpr(this) - private val bvRedOrExprCache = mkClosableCache { value: KExpr -> KBvReductionOrExpr(this, value) } + private val bvRedOrExprCache = mkClosableCache { value: KExpr -> + KBvReductionOrExpr(this, value) + } + fun mkBvReductionOrExpr(value: KExpr): KBvReductionOrExpr = bvRedOrExprCache.createIfContextActive(value.cast()).cast() fun KExpr.reductionOr(): KBvReductionOrExpr = mkBvReductionOrExpr(this) - private val bvAndExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvAndExpr(this, arg0, arg1) } + private val bvAndExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvAndExpr(this, arg0, arg1) + } fun mkBvAndExpr(arg0: KExpr, arg1: KExpr): KBvAndExpr = bvAndExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvOrExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvOrExpr(this, arg0, arg1) } + private val bvOrExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvOrExpr(this, arg0, arg1) + } fun mkBvOrExpr(arg0: KExpr, arg1: KExpr): KBvOrExpr = bvOrExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvXorExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvXorExpr(this, arg0, arg1) } + private val bvXorExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvXorExpr(this, arg0, arg1) + } fun mkBvXorExpr(arg0: KExpr, arg1: KExpr): KBvXorExpr = bvXorExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvNAndExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvNAndExpr(this, arg0, arg1) } + private val bvNAndExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvNAndExpr(this, arg0, arg1) + } fun mkBvNAndExpr(arg0: KExpr, arg1: KExpr): KBvNAndExpr = bvNAndExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvNorExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvNorExpr(this, arg0, arg1) } + private val bvNorExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvNorExpr(this, arg0, arg1) + } fun mkBvNorExpr(arg0: KExpr, arg1: KExpr): KBvNorExpr = bvNorExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvXNorExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvXNorExpr(this, arg0, arg1) } + private val bvXNorExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvXNorExpr(this, arg0, arg1) + } fun mkBvXNorExpr(arg0: KExpr, arg1: KExpr): KBvXNorExpr = bvXNorExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvNegationExprCache = mkClosableCache { value: KExpr -> KBvNegationExpr(this, value) } + private val bvNegationExprCache = mkClosableCache { value: KExpr -> + KBvNegationExpr(this, value) + } + fun mkBvNegationExpr(value: KExpr): KBvNegationExpr = bvNegationExprCache.createIfContextActive(value.cast()).cast() - private val bvAddExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvAddExpr(this, arg0, arg1) } + private val bvAddExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvAddExpr(this, arg0, arg1) + } fun mkBvAddExpr(arg0: KExpr, arg1: KExpr): KBvAddExpr = bvAddExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvSubExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvSubExpr(this, arg0, arg1) } + private val bvSubExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvSubExpr(this, arg0, arg1) + } fun mkBvSubExpr(arg0: KExpr, arg1: KExpr): KBvSubExpr = bvSubExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvMulExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvMulExpr(this, arg0, arg1) } + private val bvMulExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvMulExpr(this, arg0, arg1) + } fun mkBvMulExpr(arg0: KExpr, arg1: KExpr): KBvMulExpr = bvMulExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvUnsignedDivExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvUnsignedDivExpr(this, arg0, arg1) } + private val bvUnsignedDivExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvUnsignedDivExpr(this, arg0, arg1) + } fun mkBvUnsignedDivExpr(arg0: KExpr, arg1: KExpr): KBvUnsignedDivExpr = bvUnsignedDivExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvSignedDivExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvSignedDivExpr(this, arg0, arg1) } + private val bvSignedDivExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvSignedDivExpr(this, arg0, arg1) + } fun mkBvSignedDivExpr(arg0: KExpr, arg1: KExpr): KBvSignedDivExpr = bvSignedDivExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvUnsignedRemExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvUnsignedRemExpr(this, arg0, arg1) } + private val bvUnsignedRemExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvUnsignedRemExpr(this, arg0, arg1) + } fun mkBvUnsignedRemExpr(arg0: KExpr, arg1: KExpr): KBvUnsignedRemExpr = bvUnsignedRemExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvSignedRemExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvSignedRemExpr(this, arg0, arg1) } + private val bvSignedRemExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvSignedRemExpr(this, arg0, arg1) + } fun mkBvSignedRemExpr(arg0: KExpr, arg1: KExpr): KBvSignedRemExpr = bvSignedRemExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvSignedModExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvSignedModExpr(this, arg0, arg1) } + private val bvSignedModExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvSignedModExpr(this, arg0, arg1) + } fun mkBvSignedModExpr(arg0: KExpr, arg1: KExpr): KBvSignedModExpr = bvSignedModExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvUnsignedLessExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvUnsignedLessExpr(this, arg0, arg1) } + private val bvUnsignedLessExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvUnsignedLessExpr(this, arg0, arg1) + } fun mkBvUnsignedLessExpr(arg0: KExpr, arg1: KExpr): KBvUnsignedLessExpr = bvUnsignedLessExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvSignedLessExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvSignedLessExpr(this, arg0, arg1) } + private val bvSignedLessExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvSignedLessExpr(this, arg0, arg1) + } fun mkBvSignedLessExpr(arg0: KExpr, arg1: KExpr): KBvSignedLessExpr = bvSignedLessExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvSignedLessOrEqualExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvSignedLessOrEqualExpr(this, arg0, arg1) } + private val bvSignedLessOrEqualExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvSignedLessOrEqualExpr(this, arg0, arg1) + } fun mkBvSignedLessOrEqualExpr(arg0: KExpr, arg1: KExpr): KBvSignedLessOrEqualExpr = bvSignedLessOrEqualExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvUnsignedLessOrEqualExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvUnsignedLessOrEqualExpr(this, arg0, arg1) } + private val bvUnsignedLessOrEqualExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvUnsignedLessOrEqualExpr(this, arg0, arg1) + } fun mkBvUnsignedLessOrEqualExpr( arg0: KExpr, arg1: KExpr - ): KBvUnsignedLessOrEqualExpr = - bvUnsignedLessOrEqualExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() + ): KBvUnsignedLessOrEqualExpr { + val a0: KExpr = arg0.cast() + val a1: KExpr = arg1.cast() - private val bvUnsignedGreaterOrEqualExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> - KBvUnsignedGreaterOrEqualExpr(this, arg0, arg1) - } + return bvUnsignedLessOrEqualExprCache.createIfContextActive(a0, a1).cast() + } + + private val bvUnsignedGreaterOrEqualExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvUnsignedGreaterOrEqualExpr(this, arg0, arg1) + } fun mkBvUnsignedGreaterOrEqualExpr( arg0: KExpr, arg1: KExpr - ): KBvUnsignedGreaterOrEqualExpr = - bvUnsignedGreaterOrEqualExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() + ): KBvUnsignedGreaterOrEqualExpr { + val a0: KExpr = arg0.cast() + val a1: KExpr = arg1.cast() - private val bvSignedGreaterOrEqualExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvSignedGreaterOrEqualExpr(this, arg0, arg1) } + return bvUnsignedGreaterOrEqualExprCache.createIfContextActive(a0, a1).cast() + } + + private val bvSignedGreaterOrEqualExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvSignedGreaterOrEqualExpr(this, arg0, arg1) + } fun mkBvSignedGreaterOrEqualExpr( arg0: KExpr, arg1: KExpr - ): KBvSignedGreaterOrEqualExpr = - bvSignedGreaterOrEqualExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() + ): KBvSignedGreaterOrEqualExpr { + val a0: KExpr = arg0.cast() + val a1: KExpr = arg1.cast() + + return bvSignedGreaterOrEqualExprCache.createIfContextActive(a0, a1).cast() + } - private val bvUnsignedGreaterExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvUnsignedGreaterExpr(this, arg0, arg1) } + private val bvUnsignedGreaterExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvUnsignedGreaterExpr(this, arg0, arg1) + } fun mkBvUnsignedGreaterExpr(arg0: KExpr, arg1: KExpr): KBvUnsignedGreaterExpr = bvUnsignedGreaterExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvSignedGreaterExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvSignedGreaterExpr(this, arg0, arg1) } + private val bvSignedGreaterExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvSignedGreaterExpr(this, arg0, arg1) + } fun mkBvSignedGreaterExpr(arg0: KExpr, arg1: KExpr): KBvSignedGreaterExpr = bvSignedGreaterExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val concatExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvConcatExpr(this, arg0, arg1) } + private val concatExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvConcatExpr(this, arg0, arg1) + } fun mkBvConcatExpr(arg0: KExpr, arg1: KExpr): KBvConcatExpr = concatExprCache.createIfContextActive(arg0.cast(), arg1.cast()) - private val extractExprCache = mkClosableCache { high: Int, low: Int, value: KExpr -> + private val extractExprCache = mkClosableCache { high: Int, + low: Int, + value: KExpr -> KBvExtractExpr(this, high, low, value) } fun mkBvExtractExpr(high: Int, low: Int, value: KExpr) = extractExprCache.createIfContextActive(high, low, value.cast()) - private val signExtensionExprCache = - mkClosableCache { i: Int, value: KExpr -> KBvSignExtensionExpr(this, i, value) } + private val signExtensionExprCache = mkClosableCache { i: Int, + value: KExpr -> + KBvSignExtensionExpr(this, i, value) + } - fun mkBvSignExtensionExpr(i: Int, value: KExpr) = - signExtensionExprCache.createIfContextActive(i, value.cast()) + fun mkBvSignExtensionExpr( + i: Int, + value: KExpr + ) = signExtensionExprCache.createIfContextActive(i, value.cast()) - private val zeroExtensionExprCache = - mkClosableCache { i: Int, value: KExpr -> KBvZeroExtensionExpr(this, i, value) } + private val zeroExtensionExprCache = mkClosableCache { i: Int, + value: KExpr -> + KBvZeroExtensionExpr(this, i, value) + } - fun mkBvZeroExtensionExpr(i: Int, value: KExpr) = - zeroExtensionExprCache.createIfContextActive(i, value.cast()) + fun mkBvZeroExtensionExpr( + i: Int, + value: KExpr + ) = zeroExtensionExprCache.createIfContextActive(i, value.cast()) - private val repeatExprCache = mkClosableCache { i: Int, value: KExpr -> KBvRepeatExpr(this, i, value) } - fun mkBvRepeatExpr(i: Int, value: KExpr) = repeatExprCache.createIfContextActive(i, value.cast()) + private val repeatExprCache = mkClosableCache { i: Int, + value: KExpr -> + KBvRepeatExpr(this, i, value) + } - private val bvShiftLeftExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvShiftLeftExpr(this, arg0, arg1) } + fun mkBvRepeatExpr( + i: Int, + value: KExpr + ) = repeatExprCache.createIfContextActive(i, value.cast()) + + private val bvShiftLeftExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvShiftLeftExpr(this, arg0, arg1) + } fun mkBvShiftLeftExpr(arg0: KExpr, arg1: KExpr): KBvShiftLeftExpr = bvShiftLeftExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvLogicalShiftRightExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvLogicalShiftRightExpr(this, arg0, arg1) } + private val bvLogicalShiftRightExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvLogicalShiftRightExpr(this, arg0, arg1) + } fun mkBvLogicalShiftRightExpr(arg0: KExpr, arg1: KExpr): KBvLogicalShiftRightExpr = bvLogicalShiftRightExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvArithShiftRightExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvArithShiftRightExpr(this, arg0, arg1) } + private val bvArithShiftRightExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvArithShiftRightExpr(this, arg0, arg1) + } fun mkBvArithShiftRightExpr(arg0: KExpr, arg1: KExpr): KBvArithShiftRightExpr = bvArithShiftRightExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvRotateLeftExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvRotateLeftExpr(this, arg0, arg1) } + private val bvRotateLeftExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvRotateLeftExpr(this, arg0, arg1) + } fun mkBvRotateLeftExpr(arg0: KExpr, arg1: KExpr): KBvRotateLeftExpr = bvRotateLeftExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvRotateLeftIndexedExprCache = - mkClosableCache { i: Int, value: KExpr -> KBvRotateLeftIndexedExpr(this, i, value) } + private val bvRotateLeftIndexedExprCache = mkClosableCache { i: Int, + value: KExpr -> + KBvRotateLeftIndexedExpr(this, i, value) + } fun mkBvRotateLeftIndexedExpr(i: Int, value: KExpr): KBvRotateLeftIndexedExpr = bvRotateLeftIndexedExprCache.createIfContextActive(i, value.cast()).cast() @@ -1035,15 +1177,19 @@ open class KContext : AutoCloseable { fun mkBvRotateLeftExpr(arg0: Int, arg1: KExpr): KBvRotateLeftExpr = mkBvRotateLeftExpr(mkBv(arg0, arg1.sort().sizeBits), arg1.cast()).cast() - private val bvRotateRightIndexedExprCache = - mkClosableCache { i: Int, value: KExpr -> KBvRotateRightIndexedExpr(this, i, value) } + private val bvRotateRightIndexedExprCache = mkClosableCache { i: Int, + value: KExpr -> + KBvRotateRightIndexedExpr(this, i, value) + } fun mkBvRotateRightIndexedExpr(i: Int, value: KExpr): KBvRotateRightIndexedExpr = bvRotateRightIndexedExprCache.createIfContextActive(i, value.cast()).cast() - private val bvRotateRightExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> KBvRotateRightExpr(this, arg0, arg1) } + private val bvRotateRightExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvRotateRightExpr(this, arg0, arg1) + } fun mkBvRotateRightExpr(arg0: KExpr, arg1: KExpr): KBvRotateRightExpr = bvRotateRightExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() @@ -1051,79 +1197,69 @@ open class KContext : AutoCloseable { fun mkBvRotateRightExpr(arg0: Int, arg1: KExpr): KBvRotateRightExpr = mkBvRotateRightExpr(mkBv(arg0, arg1.sort().sizeBits), arg1.cast()).cast() - private val bv2IntExprCache = - mkClosableCache { value: KExpr, isSigned: Boolean -> KBv2IntExpr(this, value, isSigned) } + private val bv2IntExprCache = mkClosableCache { value: KExpr, + isSigned: Boolean -> + KBv2IntExpr(this, value, isSigned) + } fun mkBv2IntExpr(value: KExpr, isSigned: Boolean): KBv2IntExpr = bv2IntExprCache.createIfContextActive(value.cast(), isSigned) - private val bvAddNoOverflowExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr, isSigned: Boolean -> - KBvAddNoOverflowExpr( - this, - arg0, - arg1, - isSigned - ) - } + private val bvAddNoOverflowExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr, + isSigned: Boolean -> + KBvAddNoOverflowExpr(this, arg0, arg1, isSigned) + } fun mkBvAddNoOverflowExpr( arg0: KExpr, arg1: KExpr, isSigned: Boolean - ): KBvAddNoOverflowExpr = - bvAddNoOverflowExprCache.createIfContextActive(arg0.cast(), arg1.cast(), isSigned).cast() - - private val bvAddNoUnderflowExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> - KBvAddNoUnderflowExpr( - this, - arg0, - arg1, - ) - } + ): KBvAddNoOverflowExpr { + val a0: KExpr = arg0.cast() + val a1: KExpr = arg1.cast() + + return bvAddNoOverflowExprCache.createIfContextActive(a0, a1, isSigned).cast() + } + + private val bvAddNoUnderflowExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvAddNoUnderflowExpr(this, arg0, arg1) + } fun mkBvAddNoUnderflowExpr(arg0: KExpr, arg1: KExpr): KBvAddNoUnderflowExpr = bvAddNoUnderflowExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvSubNoOverflowExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> - KBvSubNoOverflowExpr( - this, - arg0, - arg1, - ) - } + private val bvSubNoOverflowExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvSubNoOverflowExpr(this, arg0, arg1) + } fun mkBvSubNoOverflowExpr(arg0: KExpr, arg1: KExpr): KBvSubNoOverflowExpr = bvSubNoOverflowExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val bvSubNoUnderflowExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr, isSigned: Boolean -> - KBvSubNoUnderflowExpr( - this, - arg0, - arg1, - isSigned - ) - } + private val bvSubNoUnderflowExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr, + isSigned: Boolean -> + KBvSubNoUnderflowExpr(this, arg0, arg1, isSigned) + } fun mkBvSubNoUnderflowExpr( arg0: KExpr, arg1: KExpr, isSigned: Boolean - ): KBvSubNoUnderflowExpr = - bvSubNoUnderflowExprCache.createIfContextActive(arg0.cast(), arg1.cast(), isSigned).cast() + ): KBvSubNoUnderflowExpr { + val a0: KExpr = arg0.cast() + val a1: KExpr = arg1.cast() + return bvSubNoUnderflowExprCache.createIfContextActive(a0, a1, isSigned).cast() + } - private val bvDivNoOverflowExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> - KBvDivNoOverflowExpr( - this, - arg0, - arg1, - ) - } + + private val bvDivNoOverflowExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvDivNoOverflowExpr(this, arg0, arg1) + } fun mkBvDivNoOverflowExpr(arg0: KExpr, arg1: KExpr): KBvDivNoOverflowExpr = bvDivNoOverflowExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() @@ -1134,31 +1270,27 @@ open class KContext : AutoCloseable { fun mkBvNegationNoOverflowExpr(value: KExpr): KBvNegNoOverflowExpr = bvNegNoOverflowExprCache.createIfContextActive(value.cast()).cast() - private val bvMulNoOverflowExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr, isSigned: Boolean -> - KBvMulNoOverflowExpr( - this, - arg0, - arg1, - isSigned - ) - } + private val bvMulNoOverflowExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr, + isSigned: Boolean -> + KBvMulNoOverflowExpr(this, arg0, arg1, isSigned) + } fun mkBvMulNoOverflowExpr( arg0: KExpr, arg1: KExpr, isSigned: Boolean - ): KBvMulNoOverflowExpr = - bvMulNoOverflowExprCache.createIfContextActive(arg0.cast(), arg1.cast(), isSigned).cast() - - private val bvMulNoUnderflowExprCache = - mkClosableCache { arg0: KExpr, arg1: KExpr -> - KBvMulNoUnderflowExpr( - this, - arg0, - arg1, - ) - } + ): KBvMulNoOverflowExpr { + val a0: KExpr = arg0.cast() + val a1: KExpr = arg1.cast() + + return bvMulNoOverflowExprCache.createIfContextActive(a0, a1, isSigned).cast() + } + + private val bvMulNoUnderflowExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> + KBvMulNoUnderflowExpr(this, arg0, arg1) + } fun mkBvMulNoUnderflowExpr(arg0: KExpr, arg1: KExpr): KBvMulNoUnderflowExpr = bvMulNoUnderflowExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() @@ -1167,17 +1299,18 @@ open class KContext : AutoCloseable { private val fp16Cache = mkClosableCache { value: Float -> KFp16Value(this, value) } private val fp32Cache = mkClosableCache { value: Float -> KFp32Value(this, value) } private val fp64Cache = mkClosableCache { value: Double -> KFp64Value(this, value) } - private val fp128Cache = mkClosableCache { significand: Long, exponent: Long, signBit: Boolean -> + private val fp128Cache = mkClosableCache { significand: Long, + exponent: Long, + signBit: Boolean -> KFp128Value(this, significand, exponent, signBit) } - private val fpCustomSizeCache = - mkClosableCache { significandSize: UInt, - exponentSize: UInt, - significand: Long, - exponent: Long, - signBit: Boolean -> - KFpCustomSizeValue(this, significandSize, exponentSize, significand, exponent, signBit) - } + private val fpCustomSizeCache = mkClosableCache { significandSize: UInt, + exponentSize: UInt, + significand: Long, + exponent: Long, + signBit: Boolean -> + KFpCustomSizeValue(this, significandSize, exponentSize, significand, exponent, signBit) + } /** * Creates FP16 from the [value]. @@ -1223,9 +1356,13 @@ open class KContext : AutoCloseable { mkFp64(number).cast() } is KFp128Sort -> mkFp128(significand, exponent, signBit).cast() - else -> fpCustomSizeCache.createIfContextActive( - significandSize, exponentSize, significand, exponent, signBit - ).cast() + else -> { + val fpValue = fpCustomSizeCache.createIfContextActive( + significandSize, exponentSize, significand, exponent, signBit + ) + + fpValue.cast() + } } } @@ -1369,17 +1506,29 @@ open class KContext : AutoCloseable { is KFpCustomSizeSort -> TODO("custom fp zero exponent") } - private val roundingModeCache = mkClosableCache { value: KFpRoundingMode -> KFpRoundingModeExpr(this, value) } - fun mkFpRoundingModeExpr(value: KFpRoundingMode): KFpRoundingModeExpr = - roundingModeCache.createIfContextActive(value) + private val roundingModeCache = mkClosableCache { value: KFpRoundingMode -> + KFpRoundingModeExpr(this, value) + } - private val fpAbsExprCache = mkClosableCache { value: KExpr -> KFpAbsExpr(this, value) } - fun mkFpAbsExpr(value: KExpr): KFpAbsExpr = - fpAbsExprCache.createIfContextActive(value.cast()).cast() + fun mkFpRoundingModeExpr( + value: KFpRoundingMode + ): KFpRoundingModeExpr = roundingModeCache.createIfContextActive(value) - private val fpNegationExprCache = mkClosableCache { value: KExpr -> KFpNegationExpr(this, value) } - fun mkFpNegationExpr(value: KExpr): KFpNegationExpr = - fpNegationExprCache.createIfContextActive(value.cast()).cast() + private val fpAbsExprCache = mkClosableCache { value: KExpr -> + KFpAbsExpr(this, value) + } + + fun mkFpAbsExpr( + value: KExpr + ): KFpAbsExpr = fpAbsExprCache.createIfContextActive(value.cast()).cast() + + private val fpNegationExprCache = mkClosableCache { value: KExpr -> + KFpNegationExpr(this, value) + } + + fun mkFpNegationExpr( + value: KExpr + ): KFpNegationExpr = fpNegationExprCache.createIfContextActive(value.cast()).cast() private val fpAddExprCache = mkClosableCache { roundingMode: KExpr, arg0: KExpr, @@ -1391,7 +1540,13 @@ open class KContext : AutoCloseable { roundingMode: KExpr, arg0: KExpr, arg1: KExpr - ): KFpAddExpr = fpAddExprCache.createIfContextActive(roundingMode.cast(), arg0.cast(), arg1.cast()).cast() + ): KFpAddExpr { + val rm = roundingMode.cast() + val a0: KExpr = arg0.cast() + val a1: KExpr = arg1.cast() + + return fpAddExprCache.createIfContextActive(rm, a0, a1).cast() + } private val fpSubExprCache = mkClosableCache { roundingMode: KExpr, @@ -1404,29 +1559,49 @@ open class KContext : AutoCloseable { roundingMode: KExpr, arg0: KExpr, arg1: KExpr - ): KFpSubExpr = fpSubExprCache.createIfContextActive(roundingMode.cast(), arg0.cast(), arg1.cast()).cast() + ): KFpSubExpr { + val rm = roundingMode.cast() + val a0: KExpr = arg0.cast() + val a1: KExpr = arg1.cast() - private val fpMulExprCache = - mkClosableCache { roundingMode: KExpr, arg0: KExpr, arg1: KExpr -> - KFpMulExpr(this, roundingMode, arg0, arg1) - } + return fpSubExprCache.createIfContextActive(rm, a0, a1).cast() + } + + private val fpMulExprCache = mkClosableCache { roundingMode: KExpr, + arg0: KExpr, + arg1: KExpr -> + KFpMulExpr(this, roundingMode, arg0, arg1) + } fun mkFpMulExpr( roundingMode: KExpr, arg0: KExpr, arg1: KExpr - ): KFpMulExpr = fpMulExprCache.createIfContextActive(roundingMode.cast(), arg0.cast(), arg1.cast()).cast() + ): KFpMulExpr { + val rm = roundingMode.cast() + val a0: KExpr = arg0.cast() + val a1: KExpr = arg1.cast() - private val fpDivExprCache = - mkClosableCache { roundingMode: KExpr, arg0: KExpr, arg1: KExpr -> - KFpDivExpr(this, roundingMode, arg0, arg1) - } + return fpMulExprCache.createIfContextActive(rm, a0, a1).cast() + } + + private val fpDivExprCache = mkClosableCache { roundingMode: KExpr, + arg0: KExpr, + arg1: KExpr -> + KFpDivExpr(this, roundingMode, arg0, arg1) + } fun mkFpDivExpr( roundingMode: KExpr, arg0: KExpr, arg1: KExpr - ): KFpDivExpr = fpDivExprCache.createIfContextActive(roundingMode.cast(), arg0.cast(), arg1.cast()).cast() + ): KFpDivExpr { + val rm = roundingMode.cast() + val a0: KExpr = arg0.cast() + val a1: KExpr = arg1.cast() + + return fpDivExprCache.createIfContextActive(rm, a0, a1).cast() + } private val fpFusedMulAddExprCache = mkClosableCache { roundingMode: KExpr, arg0: KExpr, @@ -1440,117 +1615,154 @@ open class KContext : AutoCloseable { arg0: KExpr, arg1: KExpr, arg2: KExpr - ): KFpFusedMulAddExpr = - fpFusedMulAddExprCache.createIfContextActive(roundingMode.cast(), arg0.cast(), arg1.cast(), arg2.cast()).cast() + ): KFpFusedMulAddExpr { + val rm = roundingMode.cast() + val a0: KExpr = arg0.cast() + val a1: KExpr = arg1.cast() + val a2: KExpr = arg2.cast() - private val fpSqrtExprCache = mkClosableCache { roundingMode: KExpr, value: KExpr -> + return fpFusedMulAddExprCache.createIfContextActive(rm, a0, a1, a2).cast() + } + + private val fpSqrtExprCache = mkClosableCache { roundingMode: KExpr, + value: KExpr -> KFpSqrtExpr(this, roundingMode, value) } fun mkFpSqrtExpr( roundingMode: KExpr, value: KExpr - ): KFpSqrtExpr = - fpSqrtExprCache.createIfContextActive(roundingMode.cast(), value.cast()).cast() + ): KFpSqrtExpr { + val rm = roundingMode.cast() + val arg: KExpr = value.cast() + + return fpSqrtExprCache.createIfContextActive(rm, arg).cast() + } - private val fpRemExprCache = mkClosableCache { arg0: KExpr, arg1: KExpr -> + private val fpRemExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> KFpRemExpr(this, arg0, arg1) } fun mkFpRemExpr(arg0: KExpr, arg1: KExpr): KFpRemExpr = fpRemExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val fpRoundToIntegralExprCache = - mkClosableCache { roundingMode: KExpr, value: KExpr -> - KFpRoundToIntegralExpr(this, roundingMode, value) - } + private val fpRoundToIntegralExprCache = mkClosableCache { roundingMode: KExpr, + value: KExpr -> + KFpRoundToIntegralExpr(this, roundingMode, value) + } fun mkFpRoundToIntegralExpr( roundingMode: KExpr, value: KExpr - ): KFpRoundToIntegralExpr = - fpRoundToIntegralExprCache.createIfContextActive(roundingMode.cast(), value.cast()).cast() + ): KFpRoundToIntegralExpr { + val rm = roundingMode.cast() + val arg: KExpr = value.cast() - private val fpMinExprCache = mkClosableCache { arg0: KExpr, arg1: KExpr -> + return fpRoundToIntegralExprCache.createIfContextActive(rm, arg).cast() + } + + private val fpMinExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> KFpMinExpr(this, arg0, arg1) } fun mkFpMinExpr(arg0: KExpr, arg1: KExpr): KFpMinExpr = fpMinExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val fpMaxExprCache = mkClosableCache { arg0: KExpr, arg1: KExpr -> + private val fpMaxExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> KFpMaxExpr(this, arg0, arg1) } fun mkFpMaxExpr(arg0: KExpr, arg1: KExpr): KFpMaxExpr = fpMaxExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val fpLessOrEqualExprCache = mkClosableCache { arg0: KExpr, arg1: KExpr -> + private val fpLessOrEqualExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> KFpLessOrEqualExpr(this, arg0, arg1) } fun mkFpLessOrEqualExpr(arg0: KExpr, arg1: KExpr): KFpLessOrEqualExpr = fpLessOrEqualExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val fpLessExprCache = mkClosableCache { arg0: KExpr, arg1: KExpr -> + private val fpLessExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> KFpLessExpr(this, arg0, arg1) } fun mkFpLessExpr(arg0: KExpr, arg1: KExpr): KFpLessExpr = fpLessExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val fpGreaterOrEqualExprCache = mkClosableCache { arg0: KExpr, arg1: KExpr -> + private val fpGreaterOrEqualExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> KFpGreaterOrEqualExpr(this, arg0, arg1) } fun mkFpGreaterOrEqualExpr(arg0: KExpr, arg1: KExpr): KFpGreaterOrEqualExpr = fpGreaterOrEqualExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val fpGreaterExprCache = mkClosableCache { arg0: KExpr, arg1: KExpr -> + private val fpGreaterExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> KFpGreaterExpr(this, arg0, arg1) } fun mkFpGreaterExpr(arg0: KExpr, arg1: KExpr): KFpGreaterExpr = fpGreaterExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val fpEqualExprCache = mkClosableCache { arg0: KExpr, arg1: KExpr -> + private val fpEqualExprCache = mkClosableCache { arg0: KExpr, + arg1: KExpr -> KFpEqualExpr(this, arg0, arg1) } fun mkFpEqualExpr(arg0: KExpr, arg1: KExpr): KFpEqualExpr = fpEqualExprCache.createIfContextActive(arg0.cast(), arg1.cast()).cast() - private val fpIsNormalExprCache = mkClosableCache { value: KExpr -> KFpIsNormalExpr(this, value) } + private val fpIsNormalExprCache = mkClosableCache { value: KExpr -> + KFpIsNormalExpr(this, value) + } fun mkFpIsNormalExpr(value: KExpr): KFpIsNormalExpr = fpIsNormalExprCache.createIfContextActive(value.cast()).cast() - private val fpIsSubnormalExprCache = mkClosableCache { value: KExpr -> KFpIsSubnormalExpr(this, value) } + private val fpIsSubnormalExprCache = mkClosableCache { value: KExpr -> + KFpIsSubnormalExpr(this, value) + } fun mkFpIsSubnormalExpr(value: KExpr): KFpIsSubnormalExpr = fpIsSubnormalExprCache.createIfContextActive(value.cast()).cast() - private val fpIsZeroExprCache = mkClosableCache { value: KExpr -> KFpIsZeroExpr(this, value) } + private val fpIsZeroExprCache = mkClosableCache { value: KExpr -> + KFpIsZeroExpr(this, value) + } fun mkFpIsZeroExpr(value: KExpr): KFpIsZeroExpr = fpIsZeroExprCache.createIfContextActive(value.cast()).cast() - private val fpIsInfiniteExprCache = mkClosableCache { value: KExpr -> KFpIsInfiniteExpr(this, value) } + private val fpIsInfiniteExprCache = mkClosableCache { value: KExpr -> + KFpIsInfiniteExpr(this, value) + } fun mkFpIsInfiniteExpr(value: KExpr): KFpIsInfiniteExpr = fpIsInfiniteExprCache.createIfContextActive(value.cast()).cast() - private val fpIsNaNExprCache = mkClosableCache { value: KExpr -> KFpIsNaNExpr(this, value) } + private val fpIsNaNExprCache = mkClosableCache { value: KExpr -> + KFpIsNaNExpr(this, value) + } fun mkFpIsNaNExpr(value: KExpr): KFpIsNaNExpr = fpIsNaNExprCache.createIfContextActive(value.cast()).cast() - private val fpIsNegativeExprCache = mkClosableCache { value: KExpr -> KFpIsNegativeExpr(this, value) } + private val fpIsNegativeExprCache = mkClosableCache { value: KExpr -> + KFpIsNegativeExpr(this, value) + } fun mkFpIsNegativeExpr(value: KExpr): KFpIsNegativeExpr = fpIsNegativeExprCache.createIfContextActive(value.cast()).cast() - private val fpIsPositiveExprCache = mkClosableCache { value: KExpr -> KFpIsPositiveExpr(this, value) } + private val fpIsPositiveExprCache = mkClosableCache { value: KExpr -> + KFpIsPositiveExpr(this, value) + } fun mkFpIsPositiveExpr(value: KExpr): KFpIsPositiveExpr = fpIsPositiveExprCache.createIfContextActive(value.cast()).cast() @@ -1567,15 +1779,23 @@ open class KContext : AutoCloseable { value: KExpr, bvSize: Int, isSigned: Boolean - ): KFpToBvExpr = - fpToBvExprCache.createIfContextActive(roundingMode.cast(), value.cast(), bvSize, isSigned).cast() + ): KFpToBvExpr { + val rm = roundingMode.cast() + val arg: KExpr = value.cast() + + return fpToBvExprCache.createIfContextActive(rm, arg, bvSize, isSigned).cast() + } - private val fpToRealExprCache = mkClosableCache { value: KExpr -> KFpToRealExpr(this, value) } + private val fpToRealExprCache = mkClosableCache { value: KExpr -> + KFpToRealExpr(this, value) + } fun mkFpToRealExpr(value: KExpr): KFpToRealExpr = fpToRealExprCache.createIfContextActive(value.cast()).cast() - private val fpToIEEEBvExprCache = mkClosableCache { value: KExpr -> KFpToIEEEBvExpr(this, value) } + private val fpToIEEEBvExprCache = mkClosableCache { value: KExpr -> + KFpToIEEEBvExpr(this, value) + } fun mkFpToIEEEBvExpr(value: KExpr): KFpToIEEEBvExpr = fpToIEEEBvExprCache.createIfContextActive(value.cast()).cast() @@ -1583,9 +1803,14 @@ open class KContext : AutoCloseable { private val fpFromBvExprCache = mkClosableCache { sign: KExpr, exponent: KExpr, significand: KExpr -> - val sort = mkFpSort(exponent.sort.sizeBits, significand.sort.sizeBits + 1u) + val exponentBits = exponent.sort.sizeBits + // +1 it required since bv doesn't contain `hidden bit` + val significandBits = significand.sort.sizeBits + 1u + val sort = mkFpSort(exponentBits, significandBits) + KFpFromBvExpr(this, sort, sign, exponent, significand) } + fun mkFpFromBvExpr( sign: KExpr, exponent: KExpr, @@ -1638,7 +1863,8 @@ open class KContext : AutoCloseable { fun mkExistentialQuantifier(body: KExpr, bounds: List>) = existentialQuantifierCache.createIfContextActive(body, bounds) - private val universalQuantifierCache = mkClosableCache { body: KExpr, bounds: List> -> + private val universalQuantifierCache = mkClosableCache { body: KExpr, + bounds: List> -> ensureContextMatch(body) ensureContextMatch(bounds) KUniversalQuantifier(this, body, bounds) @@ -1667,8 +1893,15 @@ open class KContext : AutoCloseable { KFuncDecl(this, name, sort, args) } - fun mkFuncDecl(name: String, sort: T, args: List): KFuncDecl = - if (args.isEmpty()) mkConstDecl(name, sort) else funcDeclCache.createIfContextActive(name, sort, args).cast() + fun mkFuncDecl( + name: String, + sort: T, + args: List + ): KFuncDecl = if (args.isEmpty()) { + mkConstDecl(name, sort) + } else { + funcDeclCache.createIfContextActive(name, sort, args).cast() + } private val constDeclCache = mkClosableCache { name: String, sort: KSort -> ensureContextMatch(sort) @@ -1688,8 +1921,10 @@ open class KContext : AutoCloseable { private var freshConstIdx = 0 fun mkFreshFuncDecl(name: String, sort: T, args: List): KFuncDecl { if (args.isEmpty()) return mkFreshConstDecl(name, sort) + ensureContextMatch(sort) ensureContextMatch(args) + return KFuncDecl(this, "$name!fresh!${freshConstIdx++}", sort, args) } @@ -1810,26 +2045,33 @@ open class KContext : AutoCloseable { KArithGeDecl(this, arg) } - fun > mkArithGeDecl(arg: T): KArithGeDecl = arithGeDeclCache.createIfContextActive(arg).cast() + fun > mkArithGeDecl( + arg: T + ): KArithGeDecl = arithGeDeclCache.createIfContextActive(arg).cast() private val arithGtDeclCache = mkContextCheckingCache { arg: KArithSort<*> -> KArithGtDecl(this, arg) } - fun > mkArithGtDecl(arg: T): KArithGtDecl = arithGtDeclCache.createIfContextActive(arg).cast() + fun > mkArithGtDecl( + arg: T + ): KArithGtDecl = arithGtDeclCache.createIfContextActive(arg).cast() private val arithLeDeclCache = mkContextCheckingCache { arg: KArithSort<*> -> KArithLeDecl(this, arg) } - fun > mkArithLeDecl(arg: T): KArithLeDecl = arithLeDeclCache.createIfContextActive(arg).cast() + fun > mkArithLeDecl( + arg: T + ): KArithLeDecl = arithLeDeclCache.createIfContextActive(arg).cast() private val arithLtDeclCache = mkContextCheckingCache { arg: KArithSort<*> -> KArithLtDecl(this, arg) } - fun > mkArithLtDecl(arg: T): KArithLtDecl = arithLtDeclCache.createIfContextActive(arg).cast() - + fun > mkArithLtDecl( + arg: T + ): KArithLtDecl = arithLtDeclCache.createIfContextActive(arg).cast() // int private val intModDeclCache = mkClosableCache { KIntModDecl(this) } @@ -2006,10 +2248,15 @@ open class KContext : AutoCloseable { fun mkBvSignedGreaterDecl(arg0: T, arg1: T): KBvSignedGreaterDecl = bvSignedGreaterDeclCache.createIfContextActive(arg0, arg1).cast() - private val concatDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort -> KBvConcatDecl(this, arg0, arg1) } + private val concatDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort -> + KBvConcatDecl(this, arg0, arg1) + } - fun mkBvConcatDecl(arg0: KBvSort, arg1: KBvSort): KBvConcatDecl = concatDeclCache.createIfContextActive(arg0, arg1) + fun mkBvConcatDecl( + arg0: KBvSort, + arg1: KBvSort + ): KBvConcatDecl = concatDeclCache.createIfContextActive(arg0, arg1) private val extractDeclCache = mkClosableCache { high: Int, low: Int, value: KExpr -> KBvExtractDecl(this, high, low, value) @@ -2027,145 +2274,134 @@ open class KContext : AutoCloseable { private val repeatDeclCache = mkClosableCache { i: Int, value: KBvSort -> KBvRepeatDecl(this, i, value) } fun mkBvRepeatDecl(i: Int, value: KBvSort) = repeatDeclCache.createIfContextActive(i, value) - private val bvShiftLeftDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort -> KBvShiftLeftDecl(this, arg0, arg1) } + private val bvShiftLeftDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort -> + KBvShiftLeftDecl(this, arg0, arg1) + } fun mkBvShiftLeftDecl(arg0: T, arg1: T): KBvShiftLeftDecl = bvShiftLeftDeclCache.createIfContextActive(arg0, arg1).cast() - private val bvLogicalShiftRightDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort -> KBvLogicalShiftRightDecl(this, arg0, arg1) } + private val bvLogicalShiftRightDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort -> + KBvLogicalShiftRightDecl(this, arg0, arg1) + } fun mkBvLogicalShiftRightDecl(arg0: T, arg1: T): KBvLogicalShiftRightDecl = bvLogicalShiftRightDeclCache.createIfContextActive(arg0, arg1).cast() - private val bvArithShiftRightDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort -> KBvArithShiftRightDecl(this, arg0, arg1) } + private val bvArithShiftRightDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort -> + KBvArithShiftRightDecl(this, arg0, arg1) + } fun mkBvArithShiftRightDecl(arg0: T, arg1: T): KBvArithShiftRightDecl = bvArithShiftRightDeclCache.createIfContextActive(arg0, arg1).cast() - private val bvRotateLeftDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort -> KBvRotateLeftDecl(this, arg0, arg1) } + private val bvRotateLeftDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort -> + KBvRotateLeftDecl(this, arg0, arg1) + } fun mkBvRotateLeftDecl(arg0: T, arg1: T): KBvRotateLeftDecl = bvRotateLeftDeclCache.createIfContextActive(arg0, arg1).cast() - private val bvRotateLeftIndexedDeclCache = - mkClosableCache { i: Int, valueSort: KBvSort -> KBvRotateLeftIndexedDecl(this, i, valueSort) } + private val bvRotateLeftIndexedDeclCache = mkClosableCache { i: Int, + valueSort: KBvSort -> + KBvRotateLeftIndexedDecl(this, i, valueSort) + } fun mkBvRotateLeftIndexedDecl(i: Int, valueSort: T): KBvRotateLeftIndexedDecl = bvRotateLeftIndexedDeclCache.createIfContextActive(i, valueSort).cast() - private val bvRotateRightDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort -> KBvRotateRightDecl(this, arg0, arg1) } + private val bvRotateRightDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort -> + KBvRotateRightDecl(this, arg0, arg1) + } fun mkBvRotateRightDecl(arg0: T, arg1: T): KBvRotateRightDecl = bvRotateRightDeclCache.createIfContextActive(arg0, arg1).cast() - private val bvRotateRightIndexedDeclCache = - mkClosableCache { i: Int, valueSort: KBvSort -> KBvRotateRightIndexedDecl(this, i, valueSort) } + private val bvRotateRightIndexedDeclCache = mkClosableCache { i: Int, + valueSort: KBvSort -> + KBvRotateRightIndexedDecl(this, i, valueSort) + } fun mkBvRotateRightIndexedDecl(i: Int, valueSort: T): KBvRotateRightIndexedDecl = bvRotateRightIndexedDeclCache.createIfContextActive(i, valueSort).cast() - private val bv2IntDeclCache = - mkClosableCache { value: KBvSort, isSigned: Boolean -> KBv2IntDecl(this, value, isSigned) } + private val bv2IntDeclCache = mkClosableCache { value: KBvSort, + isSigned: Boolean -> + KBv2IntDecl(this, value, isSigned) + } fun mkBv2IntDecl(value: KBvSort, isSigned: Boolean) = bv2IntDeclCache.createIfContextActive(value, isSigned) - private val bvAddNoOverflowDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort, isSigned: Boolean -> - KBvAddNoOverflowDecl( - this, - arg0, - arg1, - isSigned - ) - } + private val bvAddNoOverflowDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort, + isSigned: Boolean -> + KBvAddNoOverflowDecl(this, arg0, arg1, isSigned) + } fun mkBvAddNoOverflowDecl(arg0: T, arg1: T, isSigned: Boolean): KBvAddNoOverflowDecl = bvAddNoOverflowDeclCache.createIfContextActive(arg0, arg1, isSigned).cast() - private val bvAddNoUnderflowDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort -> - KBvAddNoUnderflowDecl( - this, - arg0, - arg1, - ) - } + private val bvAddNoUnderflowDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort -> + KBvAddNoUnderflowDecl(this, arg0, arg1) + } fun mkBvAddNoUnderflowDecl(arg0: T, arg1: T): KBvAddNoUnderflowDecl = bvAddNoUnderflowDeclCache.createIfContextActive(arg0, arg1).cast() - private val bvSubNoOverflowDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort -> - KBvSubNoOverflowDecl( - this, - arg0, - arg1, - ) - } + private val bvSubNoOverflowDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort -> + KBvSubNoOverflowDecl(this, arg0, arg1) + } fun mkBvSubNoOverflowDecl(arg0: T, arg1: T): KBvSubNoOverflowDecl = bvSubNoOverflowDeclCache.createIfContextActive(arg0, arg1).cast() - private val bvSubUnderflowDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort, isSigned: Boolean -> - KBvSubNoUnderflowDecl( - this, - arg0, - arg1, - isSigned - ) - } + private val bvSubUnderflowDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort, + isSigned: Boolean -> + KBvSubNoUnderflowDecl(this, arg0, arg1, isSigned) + } fun mkBvSubNoUnderflowDecl(arg0: T, arg1: T, isSigned: Boolean): KBvSubNoUnderflowDecl = bvSubUnderflowDeclCache.createIfContextActive(arg0, arg1, isSigned).cast() - private val bvDivNoOverflowDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort -> - KBvDivNoOverflowDecl( - this, - arg0, - arg1 - ) - } + private val bvDivNoOverflowDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort -> + KBvDivNoOverflowDecl(this, arg0, arg1) + } fun mkBvDivNoOverflowDecl(arg0: T, arg1: T): KBvDivNoOverflowDecl = bvDivNoOverflowDeclCache.createIfContextActive(arg0, arg1).cast() - private val bvNegationNoOverflowDeclCache = - mkClosableCache { value: KBvSort -> KBvNegNoOverflowDecl(this, value) } + private val bvNegationNoOverflowDeclCache = mkClosableCache { value: KBvSort -> + KBvNegNoOverflowDecl(this, value) + } fun mkBvNegationNoOverflowDecl(value: T): KBvNegNoOverflowDecl = bvNegationNoOverflowDeclCache.createIfContextActive(value).cast() - private val bvMulNoOverflowDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort, isSigned: Boolean -> - KBvMulNoOverflowDecl( - this, - arg0, - arg1, - isSigned - ) - } + private val bvMulNoOverflowDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort, + isSigned: Boolean -> + KBvMulNoOverflowDecl(this, arg0, arg1, isSigned) + } fun mkBvMulNoOverflowDecl(arg0: T, arg1: T, isSigned: Boolean): KBvMulNoOverflowDecl = bvMulNoOverflowDeclCache.createIfContextActive(arg0, arg1, isSigned).cast() - private val bvMulNoUnderflowDeclCache = - mkClosableCache { arg0: KBvSort, arg1: KBvSort -> - KBvMulNoUnderflowDecl( - this, - arg0, - arg1, - ) - } + private val bvMulNoUnderflowDeclCache = mkClosableCache { arg0: KBvSort, + arg1: KBvSort -> + KBvMulNoUnderflowDecl(this, arg0, arg1) + } fun mkBvMulNoUnderflowDecl(arg0: T, arg1: T): KBvMulNoUnderflowDecl = bvMulNoUnderflowDeclCache.createIfContextActive(arg0, arg1).cast() @@ -2180,21 +2416,22 @@ open class KContext : AutoCloseable { private val fp64DeclCache = mkClosableCache { value: Double -> KFp64Decl(this, value) } fun mkFp64Decl(value: Double): KFp64Decl = fp64DeclCache.createIfContextActive(value) - private val fp128DeclCache = mkClosableCache { significand: Long, exponent: Long, signBit: Boolean -> + private val fp128DeclCache = mkClosableCache { significand: Long, + exponent: Long, + signBit: Boolean -> KFp128Decl(this, significand, exponent, signBit) } fun mkFp128Decl(significandBits: Long, exponent: Long, signBit: Boolean): KFp128Decl = fp128DeclCache.createIfContextActive(significandBits, exponent, signBit) - private val fpCustomSizeDeclCache = - mkClosableCache { significandSize: UInt, - exponentSize: UInt, - significand: Long, - exponent: Long, - signBit: Boolean -> - KFpCustomSizeDecl(this, significandSize, exponentSize, significand, exponent, signBit) - } + private val fpCustomSizeDeclCache = mkClosableCache { significandSize: UInt, + exponentSize: UInt, + significand: Long, + exponent: Long, + signBit: Boolean -> + KFpCustomSizeDecl(this, significandSize, exponentSize, significand, exponent, signBit) + } fun mkFpCustomSizeDecl( significandSize: UInt, @@ -2206,9 +2443,11 @@ open class KContext : AutoCloseable { val sort = mkFpSort(exponentSize, significandSize) if (sort is KFpCustomSizeSort) { - return fpCustomSizeDeclCache.createIfContextActive( + val fpDecl = fpCustomSizeDeclCache.createIfContextActive( significandSize, exponentSize, significand, exponent, signBit - ).cast() + ) + + return fpDecl.cast() } if (sort is KFp128Sort) { @@ -2237,25 +2476,32 @@ open class KContext : AutoCloseable { } } - private val roundingModeDeclCache = - mkClosableCache { value: KFpRoundingMode -> KFpRoundingModeDecl(this, value) } + private val roundingModeDeclCache = mkClosableCache { value: KFpRoundingMode -> + KFpRoundingModeDecl(this, value) + } fun mkFpRoundingModeDecl(value: KFpRoundingMode) = roundingModeDeclCache.createIfContextActive(value) - private val fpAbsDeclCache = mkClosableCache { valueSort: KFpSort -> KFpAbsDecl(this, valueSort) } + private val fpAbsDeclCache = mkClosableCache { valueSort: KFpSort -> + KFpAbsDecl(this, valueSort) + } - fun mkFpAbsDecl(valueSort: T): KFpAbsDecl = - fpAbsDeclCache.createIfContextActive(valueSort).cast() + fun mkFpAbsDecl( + valueSort: T + ): KFpAbsDecl = fpAbsDeclCache.createIfContextActive(valueSort).cast() - private val fpNegationDeclCache = mkClosableCache { valueSort: KFpSort -> KFpNegationDecl(this, valueSort) } + private val fpNegationDeclCache = mkClosableCache { valueSort: KFpSort -> + KFpNegationDecl(this, valueSort) + } fun mkFpNegationDecl(valueSort: T): KFpNegationDecl = fpNegationDeclCache.createIfContextActive(valueSort).cast() - private val fpAddDeclCache = - mkClosableCache { roundingMode: KFpRoundingModeSort, arg0Sort: KFpSort, arg1Sort: KFpSort -> - KFpAddDecl(this, roundingMode, arg0Sort, arg1Sort) - } + private val fpAddDeclCache = mkClosableCache { roundingMode: KFpRoundingModeSort, + arg0Sort: KFpSort, + arg1Sort: KFpSort -> + KFpAddDecl(this, roundingMode, arg0Sort, arg1Sort) + } fun mkFpAddDecl( roundingMode: KFpRoundingModeSort, @@ -2263,10 +2509,11 @@ open class KContext : AutoCloseable { arg1Sort: T ): KFpAddDecl = fpAddDeclCache.createIfContextActive(roundingMode, arg0Sort, arg1Sort).cast() - private val fpSubDeclCache = - mkClosableCache { roundingMode: KFpRoundingModeSort, arg0Sort: KFpSort, arg1Sort: KFpSort -> - KFpSubDecl(this, roundingMode, arg0Sort, arg1Sort) - } + private val fpSubDeclCache = mkClosableCache { roundingMode: KFpRoundingModeSort, + arg0Sort: KFpSort, + arg1Sort: KFpSort -> + KFpSubDecl(this, roundingMode, arg0Sort, arg1Sort) + } fun mkFpSubDecl( roundingMode: KFpRoundingModeSort, @@ -2274,10 +2521,11 @@ open class KContext : AutoCloseable { arg1Sort: T ): KFpSubDecl = fpSubDeclCache.createIfContextActive(roundingMode, arg0Sort, arg1Sort).cast() - private val fpMulDeclCache = - mkClosableCache { roundingMode: KFpRoundingModeSort, arg0Sort: KFpSort, arg1Sort: KFpSort -> - KFpMulDecl(this, roundingMode, arg0Sort, arg1Sort) - } + private val fpMulDeclCache = mkClosableCache { roundingMode: KFpRoundingModeSort, + arg0Sort: KFpSort, + arg1Sort: KFpSort -> + KFpMulDecl(this, roundingMode, arg0Sort, arg1Sort) + } fun mkFpMulDecl( roundingMode: KFpRoundingModeSort, @@ -2285,10 +2533,11 @@ open class KContext : AutoCloseable { arg1Sort: T ): KFpMulDecl = fpMulDeclCache.createIfContextActive(roundingMode, arg0Sort, arg1Sort).cast() - private val fpDivDeclCache = - mkClosableCache { roundingMode: KFpRoundingModeSort, arg0Sort: KFpSort, arg1Sort: KFpSort -> - KFpDivDecl(this, roundingMode, arg0Sort, arg1Sort) - } + private val fpDivDeclCache = mkClosableCache { roundingMode: KFpRoundingModeSort, + arg0Sort: KFpSort, + arg1Sort: KFpSort -> + KFpDivDecl(this, roundingMode, arg0Sort, arg1Sort) + } fun mkFpDivDecl( roundingMode: KFpRoundingModeSort, @@ -2296,37 +2545,48 @@ open class KContext : AutoCloseable { arg1Sort: T ): KFpDivDecl = fpDivDeclCache.createIfContextActive(roundingMode, arg0Sort, arg1Sort).cast() - private val fpFusedMulAddDeclCache = - mkClosableCache { roundingMode: KFpRoundingModeSort, arg0sort: KFpSort, arg1Sort: KFpSort, arg2Sort: KFpSort -> - KFpFusedMulAddDecl(this, roundingMode, arg0sort, arg1Sort, arg2Sort) - } + private val fpFusedMulAddDeclCache = mkClosableCache { roundingMode: KFpRoundingModeSort, + arg0sort: KFpSort, + arg1Sort: KFpSort, + arg2Sort: KFpSort -> + KFpFusedMulAddDecl(this, roundingMode, arg0sort, arg1Sort, arg2Sort) + } fun mkFpFusedMulAddDecl( roundingMode: KFpRoundingModeSort, arg0Sort: T, arg1Sort: T, arg2Sort: T - ): KFpFusedMulAddDecl = - fpFusedMulAddDeclCache.createIfContextActive(roundingMode, arg0Sort, arg1Sort, arg2Sort).cast() + ): KFpFusedMulAddDecl { + val fpDecl = fpFusedMulAddDeclCache.createIfContextActive( + roundingMode, + arg0Sort, + arg1Sort, + arg2Sort + ) + return fpDecl.cast() + } - private val fpSqrtDeclCache = mkClosableCache { roundingMode: KFpRoundingModeSort, valueSort: KFpSort -> + private val fpSqrtDeclCache = mkClosableCache { roundingMode: KFpRoundingModeSort, + valueSort: KFpSort -> KFpSqrtDecl(this, roundingMode, valueSort) } fun mkFpSqrtDecl(roundingMode: KFpRoundingModeSort, valueSort: T): KFpSqrtDecl = fpSqrtDeclCache.createIfContextActive(roundingMode, valueSort).cast() - private val fpRemDeclCache = mkClosableCache { arg0Sort: KFpSort, arg1Sort: KFpSort -> + private val fpRemDeclCache = mkClosableCache { arg0Sort: KFpSort, + arg1Sort: KFpSort -> KFpRemDecl(this, arg0Sort, arg1Sort) } fun mkFpRemDecl(arg0Sort: T, arg1Sort: T): KFpRemDecl = fpRemDeclCache.createIfContextActive(arg0Sort, arg1Sort).cast() - private val roundToIntegralDeclCache = - mkClosableCache { roundingMode: KFpRoundingModeSort, valueSort: KFpSort -> - KFpRoundToIntegralDecl(this, roundingMode, valueSort) - } + private val roundToIntegralDeclCache = mkClosableCache { roundingMode: KFpRoundingModeSort, + valueSort: KFpSort -> + KFpRoundToIntegralDecl(this, roundingMode, valueSort) + } fun mkFpRoundToIntegralDecl( roundingMode: KFpRoundingModeSort, @@ -2431,10 +2691,12 @@ open class KContext : AutoCloseable { fun mkFpIsPositiveDecl(valueSort: T): KFpIsPositiveDecl = fpIsPositiveDecl.createIfContextActive(valueSort).cast() - private val fpToBvDeclCache = - mkClosableCache { roundingMode: KFpRoundingModeSort, valueSort: KFpSort, bvSize: Int, isSigned: Boolean -> - KFpToBvDecl(this, roundingMode, valueSort, bvSize, isSigned) - } + private val fpToBvDeclCache = mkClosableCache { roundingMode: KFpRoundingModeSort, + valueSort: KFpSort, + bvSize: Int, + isSigned: Boolean -> + KFpToBvDecl(this, roundingMode, valueSort, bvSize, isSigned) + } fun mkFpToBvDecl( roundingMode: KFpRoundingModeSort, @@ -2453,26 +2715,43 @@ open class KContext : AutoCloseable { fun mkFpToIEEEBvDecl(valueSort: T): KFpToIEEEBvDecl = fpToIEEEBvDeclCache.createIfContextActive(valueSort).cast() - private val fpFromBvDeclCache = mkClosableCache { signSort: KBv1Sort, expSort: KBvSort, significandSort: KBvSort -> - val sort = mkFpSort(expSort.sizeBits, significandSort.sizeBits + 1u) + private val fpFromBvDeclCache = mkClosableCache { signSort: KBv1Sort, + expSort: KBvSort, + significandSort: KBvSort -> + val exponentBits = expSort.sizeBits + val significandBits = significandSort.sizeBits + 1u + val sort = mkFpSort(exponentBits, significandBits) + KFpFromBvDecl(this, sort, signSort, expSort, significandSort) } - fun mkFpFromBvDecl(signSort: KBv1Sort, expSort: KBvSort, significandSort: KBvSort): KFpFromBvDecl = - fpFromBvDeclCache.createIfContextActive(signSort, expSort, significandSort).cast() + fun mkFpFromBvDecl( + signSort: KBv1Sort, + expSort: KBvSort, + significandSort: KBvSort + ): KFpFromBvDecl { + val fpDecl = fpFromBvDeclCache.createIfContextActive(signSort, expSort, significandSort) + return fpDecl.cast() + } - private val fpToFpDeclCache = mkClosableCache { sort: KFpSort, rm: KFpRoundingModeSort, value: KFpSort -> + private val fpToFpDeclCache = mkClosableCache { sort: KFpSort, + rm: KFpRoundingModeSort, + value: KFpSort -> KFpToFpDecl(this, sort, rm, value) } - private val realToFpDeclCache = mkClosableCache { sort: KFpSort, rm: KFpRoundingModeSort, value: KRealSort -> + private val realToFpDeclCache = mkClosableCache { sort: KFpSort, + rm: KFpRoundingModeSort, + value: KRealSort -> KRealToFpDecl(this, sort, rm, value) } - private val bvToFpDeclCache = - mkClosableCache { sort: KFpSort, rm: KFpRoundingModeSort, value: KBvSort, signed: Boolean -> - KBvToFpDecl(this, sort, rm, value, signed) - } + private val bvToFpDeclCache = mkClosableCache { sort: KFpSort, + rm: KFpRoundingModeSort, + value: KBvSort, + signed: Boolean -> + KBvToFpDecl(this, sort, rm, value, signed) + } fun mkFpToFpDecl(sort: T, rm: KFpRoundingModeSort, value: KFpSort): KFpToFpDecl = fpToFpDeclCache.createIfContextActive(sort, rm, value).cast() @@ -2542,24 +2821,29 @@ open class KContext : AutoCloseable { private fun mkClosableCache(builder: (A0) -> T) = ensureClosed { mkCache(builder) } private fun mkClosableCache(builder: (A0, A1) -> T) = ensureClosed { mkCache(builder) } private fun mkClosableCache(builder: (A0, A1, A2) -> T) = ensureClosed { mkCache(builder) } - private fun mkClosableCache(builder: (A0, A1, A2, A3) -> T) = ensureClosed { mkCache(builder) } - private fun mkClosableCache(builder: (A0, A1, A2, A3, A4) -> T) = - ensureClosed { mkCache(builder) } + private fun mkClosableCache( + builder: (A0, A1, A2, A3) -> T + ) = ensureClosed { mkCache(builder) } + + private fun mkClosableCache( + builder: (A0, A1, A2, A3, A4) -> T + ) = ensureClosed { mkCache(builder) } - private fun Cache0.createIfContextActive(): T = - ensureContextActive { create() } + private fun Cache0.createIfContextActive(): T = ensureContextActive { create() } - private fun Cache1.createIfContextActive(arg: A): T = - ensureContextActive { create(arg) } + private fun Cache1.createIfContextActive(arg: A): T = ensureContextActive { create(arg) } - private fun Cache2.createIfContextActive(a0: A0, a1: A1): T = - ensureContextActive { create(a0, a1) } + private fun Cache2.createIfContextActive( + a0: A0, a1: A1 + ): T = ensureContextActive { create(a0, a1) } - private fun Cache3.createIfContextActive(a0: A0, a1: A1, a2: A2): T = - ensureContextActive { create(a0, a1, a2) } + private fun Cache3.createIfContextActive( + a0: A0, a1: A1, a2: A2 + ): T = ensureContextActive { create(a0, a1, a2) } - private fun Cache4.createIfContextActive(a0: A0, a1: A1, a2: A2, a3: A3): T = - ensureContextActive { create(a0, a1, a2, a3) } + private fun Cache4.createIfContextActive( + a0: A0, a1: A1, a2: A2, a3: A3 + ): T = ensureContextActive { create(a0, a1, a2, a3) } private fun Cache5.createIfContextActive( a0: A0, a1: A1, a2: A2, a3: A3, a4: A4 diff --git a/ksmt-core/src/main/kotlin/org/ksmt/cache/Cache.kt b/ksmt-core/src/main/kotlin/org/ksmt/cache/Cache.kt index 2ecf4b99b..110c6f319 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/cache/Cache.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/cache/Cache.kt @@ -8,6 +8,7 @@ class Cache0(val builder: () -> T) : AutoCloseable { if (UNINITIALIZED === value) { value = builder() } + return value as T } @@ -22,7 +23,9 @@ class Cache0(val builder: () -> T) : AutoCloseable { class Cache1(val builder: (A0) -> T) : AutoCloseable { private val cache = HashMap() + fun create(a0: A0): T = cache.getOrPut(a0) { builder(a0) } + override fun close() { cache.clear() } @@ -30,7 +33,9 @@ class Cache1(val builder: (A0) -> T) : AutoCloseable { class Cache2(val builder: (A0, A1) -> T) : AutoCloseable { private val cache = HashMap, T>() + fun create(a0: A0, a1: A1): T = cache.getOrPut(Pair(a0, a1)) { builder(a0, a1) } + override fun close() { cache.clear() } @@ -38,7 +43,9 @@ class Cache2(val builder: (A0, A1) -> T) : AutoCloseable { class Cache3(val builder: (A0, A1, A2) -> T) : AutoCloseable { private val cache = HashMap, T>() + fun create(a0: A0, a1: A1, a2: A2): T = cache.getOrPut(Triple(a0, a1, a2)) { builder(a0, a1, a2) } + override fun close() { cache.clear() } @@ -59,8 +66,11 @@ class Cache5(val builder: (A0, A1, A2, A3, A4) -> T) : Au private val cache = HashMap, T>() @Suppress("unused") - fun create(a0: A0, a1: A1, a2: A2, a3: A3, a4: A4): T = - cache.getOrPut(listOf(a0, a1, a2, a3, a4)) { builder(a0, a1, a2, a3, a4) } + fun create(a0: A0, a1: A1, a2: A2, a3: A3, a4: A4): T { + val arguments = listOf(a0, a1, a2, a3, a4) + + return cache.getOrPut(arguments) { builder(a0, a1, a2, a3, a4) } + } override fun close() { cache.clear() diff --git a/ksmt-core/src/main/kotlin/org/ksmt/decl/Array.kt b/ksmt-core/src/main/kotlin/org/ksmt/decl/Array.kt index 9bd1bb7d1..35c9b066a 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/decl/Array.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/decl/Array.kt @@ -6,8 +6,17 @@ import org.ksmt.expr.KExpr import org.ksmt.sort.KArraySort import org.ksmt.sort.KSort -class KArrayStoreDecl internal constructor(ctx: KContext, sort: KArraySort) : - KFuncDecl3, KArraySort, D, R>(ctx, "store", sort, sort, sort.domain, sort.range) { +class KArrayStoreDecl internal constructor( + ctx: KContext, + sort: KArraySort +) : KFuncDecl3, KArraySort, D, R>( + ctx, + name = "store", + resultSort = sort, + arg0Sort = sort, + arg1Sort = sort.domain, + arg2Sort = sort.range +) { override fun KContext.apply( arg0: KExpr>, arg1: KExpr, arg2: KExpr @@ -16,15 +25,28 @@ class KArrayStoreDecl internal constructor(ctx: KContext, override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KArraySelectDecl internal constructor(ctx: KContext, sort: KArraySort) : - KFuncDecl2, D>(ctx, "select", sort.range, sort, sort.domain) { - override fun KContext.apply(arg0: KExpr>, arg1: KExpr): KApp = mkArraySelect(arg0, arg1) +class KArraySelectDecl internal constructor( + ctx: KContext, + sort: KArraySort +) : KFuncDecl2, D>( + ctx, + name = "select", + resultSort = sort.range, + arg0Sort = sort, + arg1Sort = sort.domain +) { + override fun KContext.apply( + arg0: KExpr>, + arg1: KExpr + ): KApp = mkArraySelect(arg0, arg1) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KArrayConstDecl(ctx: KContext, sort: KArraySort) : - KFuncDecl1, R>(ctx, "const", sort, sort.range) { +class KArrayConstDecl( + ctx: KContext, + sort: KArraySort +) : KFuncDecl1, R>(ctx, "const", sort, sort.range) { override fun KContext.apply(arg: KExpr): KApp, KExpr> = mkArrayConst(sort, arg) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) diff --git a/ksmt-core/src/main/kotlin/org/ksmt/decl/Bool.kt b/ksmt-core/src/main/kotlin/org/ksmt/decl/Bool.kt index f9f9e2889..f0168d08d 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/decl/Bool.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/decl/Bool.kt @@ -6,66 +6,100 @@ import org.ksmt.expr.KApp import org.ksmt.sort.KBoolSort import org.ksmt.sort.KSort -class KAndDecl internal constructor(ctx: KContext) : - KFuncDeclChain(ctx, "and", ctx.mkBoolSort(), ctx.mkBoolSort()) { +class KAndDecl internal constructor( + ctx: KContext +) : KFuncDeclChain(ctx, "and", ctx.mkBoolSort(), ctx.mkBoolSort()) { override fun KContext.applyChain(args: List>): KApp> = mkAnd(args) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KOrDecl internal constructor(ctx: KContext) : - KFuncDeclChain(ctx, "or", ctx.mkBoolSort(), ctx.mkBoolSort()) { +class KOrDecl internal constructor( + ctx: KContext +) : KFuncDeclChain(ctx, "or", ctx.mkBoolSort(), ctx.mkBoolSort()) { override fun KContext.applyChain(args: List>): KApp> = mkOr(args) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KNotDecl internal constructor(ctx: KContext) : - KFuncDecl1(ctx, "not", ctx.mkBoolSort(), ctx.mkBoolSort()) { +class KNotDecl internal constructor( + ctx: KContext +) : KFuncDecl1(ctx, "not", ctx.mkBoolSort(), ctx.mkBoolSort()) { override fun KContext.apply(arg: KExpr): KApp> = mkNot(arg) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KImpliesDecl internal constructor(ctx: KContext) : - KFuncDecl2(ctx, "implies", ctx.mkBoolSort(), ctx.mkBoolSort(), ctx.mkBoolSort()) { - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp> = - mkImplies(arg0, arg1) +class KImpliesDecl internal constructor( + ctx: KContext +) : KFuncDecl2( + ctx, + name = "implies", + ctx.mkBoolSort(), + ctx.mkBoolSort(), + ctx.mkBoolSort() +) { + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp> = mkImplies(arg0, arg1) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KXorDecl internal constructor(ctx: KContext) : - KFuncDecl2(ctx, "xor", ctx.mkBoolSort(), ctx.mkBoolSort(), ctx.mkBoolSort()) { - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp> = - mkXor(arg0, arg1) +class KXorDecl internal constructor( + ctx: KContext +) : KFuncDecl2( + ctx, + name = "xor", + ctx.mkBoolSort(), + ctx.mkBoolSort(), + ctx.mkBoolSort() +) { + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp> = mkXor(arg0, arg1) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KEqDecl internal constructor(ctx: KContext, argSort: T) : - KFuncDecl2(ctx, "eq", ctx.mkBoolSort(), argSort, argSort) { +class KEqDecl internal constructor( + ctx: KContext, + argSort: T +) : KFuncDecl2(ctx, "eq", ctx.mkBoolSort(), argSort, argSort) { override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp> = mkEq(arg0, arg1) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KDistinctDecl internal constructor(ctx: KContext, argSort: T) : - KFuncDeclChain(ctx, "distinct", ctx.mkBoolSort(), argSort) { +class KDistinctDecl internal constructor( + ctx: KContext, + argSort: T +) : KFuncDeclChain(ctx, "distinct", ctx.mkBoolSort(), argSort) { override fun KContext.applyChain(args: List>): KApp> = mkDistinct(args) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KIteDecl internal constructor(ctx: KContext, argSort: T) : - KFuncDecl3(ctx, "ite", argSort, ctx.mkBoolSort(), argSort, argSort) { - override fun KContext.apply(arg0: KExpr, arg1: KExpr, arg2: KExpr): KApp = - mkIte(arg0, arg1, arg2) +class KIteDecl internal constructor( + ctx: KContext, + argSort: T +) : KFuncDecl3(ctx, "ite", argSort, ctx.mkBoolSort(), argSort, argSort) { + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr, + arg2: KExpr + ): KApp = mkIte(arg0, arg1, arg2) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KTrueDecl internal constructor(ctx: KContext) : KConstDecl(ctx, "true", ctx.mkBoolSort()) { +class KTrueDecl internal constructor( + ctx: KContext +) : KConstDecl(ctx, "true", ctx.mkBoolSort()) { override fun apply(args: List>): KApp = ctx.mkTrue() override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KFalseDecl internal constructor(ctx: KContext) : KConstDecl(ctx, "false", ctx.mkBoolSort()) { +class KFalseDecl internal constructor( + ctx: KContext +) : KConstDecl(ctx, "false", ctx.mkBoolSort()) { override fun apply(args: List>): KApp = ctx.mkFalse() override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/decl/Integer.kt b/ksmt-core/src/main/kotlin/org/ksmt/decl/Integer.kt index 1d25595b6..9dcbc5f87 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/decl/Integer.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/decl/Integer.kt @@ -6,26 +6,56 @@ import org.ksmt.expr.KApp import org.ksmt.sort.KIntSort import org.ksmt.sort.KRealSort -class KIntModDecl internal constructor(ctx: KContext) : - KFuncDecl2(ctx, "intMod", ctx.mkIntSort(), ctx.mkIntSort(), ctx.mkIntSort()) { - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkIntMod(arg0, arg1) +class KIntModDecl internal constructor( + ctx: KContext +) : KFuncDecl2( + ctx, + "intMod", + ctx.mkIntSort(), + ctx.mkIntSort(), + ctx.mkIntSort() +) { + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = mkIntMod(arg0, arg1) + override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KIntRemDecl internal constructor(ctx: KContext) : - KFuncDecl2(ctx, "intRem", ctx.mkIntSort(), ctx.mkIntSort(), ctx.mkIntSort()) { - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkIntRem(arg0, arg1) +class KIntRemDecl internal constructor( + ctx: KContext +) : KFuncDecl2( + ctx, + "intRem", + ctx.mkIntSort(), + ctx.mkIntSort(), + ctx.mkIntSort() +) { + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = mkIntRem(arg0, arg1) + override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KIntToRealDecl internal constructor(ctx: KContext) : - KFuncDecl1(ctx, "intToReal", ctx.mkRealSort(), ctx.mkIntSort()) { +class KIntToRealDecl internal constructor( + ctx: KContext +) : KFuncDecl1( + ctx, + "intToReal", + ctx.mkRealSort(), + ctx.mkIntSort() +) { override fun KContext.apply(arg: KExpr): KApp> = mkIntToReal(arg) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KIntNumDecl internal constructor(ctx: KContext, val value: String) : - KConstDecl(ctx, value, ctx.mkIntSort()) { +class KIntNumDecl internal constructor( + ctx: KContext, + val value: String +) : KConstDecl(ctx, value, ctx.mkIntSort()) { override fun apply(args: List>): KApp = ctx.mkIntNum(value) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/decl/KBitVecExprsDecl.kt b/ksmt-core/src/main/kotlin/org/ksmt/decl/KBitVecExprsDecl.kt index 1170256dd..9aa48af81 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/decl/KBitVecExprsDecl.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/decl/KBitVecExprsDecl.kt @@ -21,36 +21,50 @@ abstract class KBitVecValueDecl internal constructor( internal constructor(ctx: KContext, value: Number, sort: T) : this(ctx, value.toBinary(), sort) } -class KBitVec1ValueDecl internal constructor(ctx: KContext, private val boolValue: Boolean) : - KBitVecValueDecl(ctx, if (boolValue) "1" else "0", ctx.mkBv1Sort()) { +class KBitVec1ValueDecl internal constructor( + ctx: KContext, + val boolValue: Boolean +) : KBitVecValueDecl( + ctx, + value = if (boolValue) "1" else "0", + ctx.mkBv1Sort() +) { override fun apply(args: List>): KApp = ctx.mkBv(boolValue) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KBitVec8ValueDecl internal constructor(ctx: KContext, val byteValue: Byte) : - KBitVecValueDecl(ctx, byteValue, ctx.mkBv8Sort()) { +class KBitVec8ValueDecl internal constructor( + ctx: KContext, + val byteValue: Byte +) : KBitVecValueDecl(ctx, byteValue, ctx.mkBv8Sort()) { override fun apply(args: List>): KApp = ctx.mkBv(byteValue) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KBitVec16ValueDecl internal constructor(ctx: KContext, val shortValue: Short) : - KBitVecValueDecl(ctx, shortValue, ctx.mkBv16Sort()) { +class KBitVec16ValueDecl internal constructor( + ctx: KContext, + val shortValue: Short +) : KBitVecValueDecl(ctx, shortValue, ctx.mkBv16Sort()) { override fun apply(args: List>): KApp = ctx.mkBv(shortValue) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KBitVec32ValueDecl internal constructor(ctx: KContext, val intValue: Int) : - KBitVecValueDecl(ctx, intValue, ctx.mkBv32Sort()) { +class KBitVec32ValueDecl internal constructor( + ctx: KContext, + val intValue: Int +) : KBitVecValueDecl(ctx, intValue, ctx.mkBv32Sort()) { override fun apply(args: List>): KApp = ctx.mkBv(intValue) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KBitVec64ValueDecl internal constructor(ctx: KContext, val longValue: Long) : - KBitVecValueDecl(ctx, longValue, ctx.mkBv64Sort()) { +class KBitVec64ValueDecl internal constructor( + ctx: KContext, + val longValue: Long +) : KBitVecValueDecl(ctx, longValue, ctx.mkBv64Sort()) { override fun apply(args: List>): KApp = ctx.mkBv(longValue) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) @@ -68,29 +82,38 @@ class KBitVecCustomSizeValueDecl internal constructor( // Expressions with bit-vectors -class KBvNotDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "bvnot", resultSort = valueSort, valueSort) { +class KBvNotDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "bvnot", resultSort = valueSort, valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = mkBvNotExpr(arg) } -class KBvReductionAndDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "bvredand", resultSort = ctx.mkBv1Sort(), valueSort) { +class KBvReductionAndDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "bvredand", resultSort = ctx.mkBv1Sort(), valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = mkBvReductionAndExpr(arg) } -class KBvReductionOrDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "bvredor", resultSort = ctx.mkBv1Sort(), valueSort) { +class KBvReductionOrDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "bvredor", resultSort = ctx.mkBv1Sort(), valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = mkBvReductionOrExpr(arg) } -class KBvAndDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvand", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvAndDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvand", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -100,8 +123,11 @@ class KBvAndDecl internal constructor(ctx: KContext, arg0Sort: T, a override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvAndExpr(arg0, arg1) } -class KBvOrDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvor", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvOrDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvor", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -111,8 +137,11 @@ class KBvOrDecl internal constructor(ctx: KContext, arg0Sort: T, ar override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvOrExpr(arg0, arg1) } -class KBvXorDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvxor", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvXorDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvxor", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -122,8 +151,11 @@ class KBvXorDecl internal constructor(ctx: KContext, arg0Sort: T, a override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvXorExpr(arg0, arg1) } -class KBvNAndDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvnand", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvNAndDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvnand", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -133,8 +165,11 @@ class KBvNAndDecl internal constructor(ctx: KContext, arg0Sort: T, override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvNAndExpr(arg0, arg1) } -class KBvNorDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvnor", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvNorDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvnor", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -144,8 +179,11 @@ class KBvNorDecl internal constructor(ctx: KContext, arg0Sort: T, a override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvNorExpr(arg0, arg1) } -class KBvXNorDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvxnor", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvXNorDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvxnor", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -155,15 +193,20 @@ class KBvXNorDecl internal constructor(ctx: KContext, arg0Sort: T, override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvXNorExpr(arg0, arg1) } -class KBvNegationDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "bvneg", resultSort = valueSort, valueSort) { +class KBvNegationDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "bvneg", resultSort = valueSort, valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = mkBvNegationExpr(arg) } -class KBvAddDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvadd", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvAddDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvadd", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -173,8 +216,11 @@ class KBvAddDecl internal constructor(ctx: KContext, arg0Sort: T, a override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvAddExpr(arg0, arg1) } -class KBvSubDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvsub", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvSubDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvsub", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -184,8 +230,11 @@ class KBvSubDecl internal constructor(ctx: KContext, arg0Sort: T, a override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvSubExpr(arg0, arg1) } -class KBvMulDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvmul", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvMulDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvmul", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -195,8 +244,11 @@ class KBvMulDecl internal constructor(ctx: KContext, arg0Sort: T, a override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvMulExpr(arg0, arg1) } -class KBvUnsignedDivDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvudiv", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvUnsignedDivDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvudiv", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -206,8 +258,11 @@ class KBvUnsignedDivDecl internal constructor(ctx: KContext, arg0So override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvUnsignedDivExpr(arg0, arg1) } -class KBvSignedDivDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvsdiv", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvSignedDivDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvsdiv", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -217,8 +272,11 @@ class KBvSignedDivDecl internal constructor(ctx: KContext, arg0Sort override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvSignedDivExpr(arg0, arg1) } -class KBvUnsignedRemDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvurem", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvUnsignedRemDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvurem", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -228,8 +286,11 @@ class KBvUnsignedRemDecl internal constructor(ctx: KContext, arg0So override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvUnsignedRemExpr(arg0, arg1) } -class KBvSignedRemDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvsrem", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvSignedRemDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvsrem", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -239,8 +300,11 @@ class KBvSignedRemDecl internal constructor(ctx: KContext, arg0Sort override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvSignedRemExpr(arg0, arg1) } -class KBvSignedModDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvsmod", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvSignedModDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvsmod", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -250,30 +314,45 @@ class KBvSignedModDecl internal constructor(ctx: KContext, arg0Sort override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvSignedModExpr(arg0, arg1) } -class KBvUnsignedLessDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvult", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KBvUnsignedLessDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvult", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvUnsignedLessExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = mkBvUnsignedLessExpr(arg0, arg1) } -class KBvSignedLessDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvslt", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KBvSignedLessDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvslt", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvSignedLessExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = mkBvSignedLessExpr(arg0, arg1) } -class KBvSignedLessOrEqualDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvsle", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KBvSignedLessOrEqualDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvsle", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -287,8 +366,11 @@ class KBvSignedLessOrEqualDecl internal constructor(ctx: KContext, } -class KBvUnsignedLessOrEqualDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvule", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KBvUnsignedLessOrEqualDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvule", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -301,8 +383,11 @@ class KBvUnsignedLessOrEqualDecl internal constructor(ctx: KContext ): KApp = mkBvUnsignedLessOrEqualExpr(arg0, arg1) } -class KBvUnsignedGreaterOrEqualDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvuge", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KBvUnsignedGreaterOrEqualDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvuge", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -315,8 +400,11 @@ class KBvUnsignedGreaterOrEqualDecl internal constructor(ctx: KCont ): KApp = mkBvUnsignedGreaterOrEqualExpr(arg0, arg1) } -class KBvSignedGreaterOrEqualDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvsge", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KBvSignedGreaterOrEqualDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvsge", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -329,8 +417,11 @@ class KBvSignedGreaterOrEqualDecl internal constructor(ctx: KContex ): KApp = mkBvSignedGreaterOrEqualExpr(arg0, arg1) } -class KBvUnsignedGreaterDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvugt", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KBvUnsignedGreaterDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvugt", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -343,8 +434,11 @@ class KBvUnsignedGreaterDecl internal constructor(ctx: KContext, ar ): KApp = mkBvUnsignedGreaterExpr(arg0, arg1) } -class KBvSignedGreaterDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvsgt", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KBvSignedGreaterDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvsgt", resultSort = ctx.mkBoolSort(), arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -357,14 +451,17 @@ class KBvSignedGreaterDecl internal constructor(ctx: KContext, arg0 ): KApp = mkBvSignedGreaterExpr(arg0, arg1) } -class KBvConcatDecl internal constructor(ctx: KContext, arg0Sort: KBvSort, arg1Sort: KBvSort) : - KFuncDecl2( - ctx, - "concat", - resultSort = ctx.mkBvSort(arg0Sort.sizeBits + arg1Sort.sizeBits), - arg0Sort, - arg1Sort - ) { +class KBvConcatDecl internal constructor( + ctx: KContext, + arg0Sort: KBvSort, + arg1Sort: KBvSort +) : KFuncDecl2( + ctx, + name = "concat", + resultSort = ctx.mkBvSort(arg0Sort.sizeBits + arg1Sort.sizeBits), + arg0Sort, + arg1Sort +) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply( @@ -380,69 +477,85 @@ class KBvExtractDecl internal constructor( value: KExpr ) : KFuncDecl1( ctx, - "extract", + name = "extract", resultSort = ctx.mkBvSort((high - low + 1).toUInt()), value.sort(), ), KParameterizedFuncDecl { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg: KExpr): KApp> = - mkBvExtractExpr(high, low, arg) + override fun KContext.apply( + arg: KExpr + ): KApp> = mkBvExtractExpr(high, low, arg) override val parameters: List get() = listOf(high, low) } -class KSignExtDecl internal constructor(ctx: KContext, val i: Int, value: KBvSort) : - KFuncDecl1( - ctx, - "sign_extend", - resultSort = ctx.mkBvSort(value.sizeBits + i.toUInt()), - value, - ), KParameterizedFuncDecl { +class KSignExtDecl internal constructor( + ctx: KContext, + val i: Int, + value: KBvSort +) : KFuncDecl1( + ctx, + name = "sign_extend", + resultSort = ctx.mkBvSort(value.sizeBits + i.toUInt()), + value, +), KParameterizedFuncDecl { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg: KExpr): KApp> = - mkBvSignExtensionExpr(i, arg) + override fun KContext.apply( + arg: KExpr + ): KApp> = mkBvSignExtensionExpr(i, arg) override val parameters: List get() = listOf(i) } -class KZeroExtDecl internal constructor(ctx: KContext, val i: Int, value: KBvSort) : - KFuncDecl1( - ctx, - "zero_extend", - resultSort = ctx.mkBvSort(value.sizeBits + i.toUInt()), - value, - ), KParameterizedFuncDecl { +class KZeroExtDecl internal constructor( + ctx: KContext, + val i: Int, + value: KBvSort +) : KFuncDecl1( + ctx, + "zero_extend", + resultSort = ctx.mkBvSort(value.sizeBits + i.toUInt()), + value, +), KParameterizedFuncDecl { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg: KExpr): KApp> = - mkBvZeroExtensionExpr(i, arg) + override fun KContext.apply( + arg: KExpr + ): KApp> = mkBvZeroExtensionExpr(i, arg) override val parameters: List get() = listOf(i) } -class KBvRepeatDecl internal constructor(ctx: KContext, val i: Int, value: KBvSort) : - KFuncDecl1( - ctx, - "repeat", - resultSort = ctx.mkBvSort(value.sizeBits * i.toUInt()), - value, - ), KParameterizedFuncDecl { +class KBvRepeatDecl internal constructor( + ctx: KContext, + val i: Int, + value: KBvSort +) : KFuncDecl1( + ctx, + "repeat", + resultSort = ctx.mkBvSort(value.sizeBits * i.toUInt()), + value, +), KParameterizedFuncDecl { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg: KExpr): KApp> = - mkBvRepeatExpr(i, arg) + override fun KContext.apply( + arg: KExpr + ): KApp> = mkBvRepeatExpr(i, arg) override val parameters: List get() = listOf(i) } -class KBvShiftLeftDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvshl", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvShiftLeftDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvshl", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -452,78 +565,130 @@ class KBvShiftLeftDecl internal constructor(ctx: KContext, arg0Sort override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvShiftLeftExpr(arg0, arg1) } -class KBvLogicalShiftRightDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvlshr", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvLogicalShiftRightDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvlshr", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvLogicalShiftRightExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = mkBvLogicalShiftRightExpr(arg0, arg1) } -class KBvArithShiftRightDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "bvashr", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvArithShiftRightDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "bvashr", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = mkBvArithShiftRightExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = mkBvArithShiftRightExpr(arg0, arg1) } -class KBvRotateLeftDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "ext_rotate_left", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvRotateLeftDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "ext_rotate_left", resultSort = arg0Sort, arg0Sort, arg1Sort) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp> = mkBvRotateLeftExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp> = mkBvRotateLeftExpr(arg0, arg1) } -class KBvRotateLeftIndexedDecl internal constructor(ctx: KContext, val i: Int, valueSort: T) : - KFuncDecl1(ctx, "rotate_left", resultSort = valueSort, valueSort), KParameterizedFuncDecl { +class KBvRotateLeftIndexedDecl internal constructor( + ctx: KContext, + val i: Int, + valueSort: T +) : KFuncDecl1(ctx, "rotate_left", resultSort = valueSort, valueSort), KParameterizedFuncDecl { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg: KExpr): KApp> = - mkBvRotateLeftIndexedExpr(i, arg) + override fun KContext.apply( + arg: KExpr + ): KApp> = mkBvRotateLeftIndexedExpr(i, arg) override val parameters: List get() = listOf(i) } -class KBvRotateRightDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "ext_rotate_right", resultSort = arg0Sort, arg0Sort, arg1Sort) { +class KBvRotateRightDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2( + ctx, + "ext_rotate_right", + resultSort = arg0Sort, + arg0Sort, + arg1Sort +) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp> = mkBvRotateRightExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp> = mkBvRotateRightExpr(arg0, arg1) } -class KBvRotateRightIndexedDecl internal constructor(ctx: KContext, val i: Int, valueSort: T) : - KFuncDecl1(ctx, "rotate_right", resultSort = valueSort, valueSort), KParameterizedFuncDecl { +class KBvRotateRightIndexedDecl internal constructor( + ctx: KContext, + val i: Int, + valueSort: T +) : KFuncDecl1( + ctx, + "rotate_right", + resultSort = valueSort, + valueSort +), KParameterizedFuncDecl { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg: KExpr): KApp> = - mkBvRotateRightIndexedExpr(i, arg) + override fun KContext.apply( + arg: KExpr + ): KApp> = mkBvRotateRightIndexedExpr(i, arg) override val parameters: List get() = listOf(i) } -class KBv2IntDecl internal constructor(ctx: KContext, value: KBvSort, val isSigned: Boolean) : - KFuncDecl1(ctx, "bv2int", resultSort = ctx.mkIntSort(), value), KParameterizedFuncDecl { +class KBv2IntDecl internal constructor( + ctx: KContext, + value: KBvSort, + val isSigned: Boolean +) : KFuncDecl1( + ctx, + "bv2int", + resultSort = ctx.mkIntSort(), + value +), KParameterizedFuncDecl { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg: KExpr): KApp> = - mkBv2IntExpr(arg, isSigned) + override fun KContext.apply( + arg: KExpr + ): KApp> = mkBv2IntExpr(arg, isSigned) override val parameters: List get() = listOf(isSigned) @@ -556,14 +721,17 @@ class KBvAddNoOverflowDecl internal constructor( get() = listOf(isSigned) } -class KBvAddNoUnderflowDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2( - ctx, - "bv_add_no_underflow", - resultSort = ctx.mkBoolSort(), - arg0Sort, - arg1Sort - ) { +class KBvAddNoUnderflowDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2( + ctx, + "bv_add_no_underflow", + resultSort = ctx.mkBoolSort(), + arg0Sort, + arg1Sort +) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -576,14 +744,17 @@ class KBvAddNoUnderflowDecl internal constructor(ctx: KContext, arg ): KApp = mkBvAddNoUnderflowExpr(arg0, arg1) } -class KBvSubNoOverflowDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2( - ctx, - "bv_sub_no_overflow", - resultSort = ctx.mkBoolSort(), - arg0Sort, - arg1Sort - ) { +class KBvSubNoOverflowDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2( + ctx, + "bv_sub_no_overflow", + resultSort = ctx.mkBoolSort(), + arg0Sort, + arg1Sort +) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -623,14 +794,17 @@ class KBvSubNoUnderflowDecl internal constructor( get() = listOf(isSigned) } -class KBvDivNoOverflowDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2( - ctx, - "bv_div_no_overflow", - resultSort = ctx.mkBoolSort(), - arg0Sort, - arg1Sort - ) { +class KBvDivNoOverflowDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2( + ctx, + "bv_div_no_overflow", + resultSort = ctx.mkBoolSort(), + arg0Sort, + arg1Sort +) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } @@ -643,12 +817,20 @@ class KBvDivNoOverflowDecl internal constructor(ctx: KContext, arg0 ): KApp = mkBvDivNoOverflowExpr(arg0, arg1) } -class KBvNegNoOverflowDecl internal constructor(ctx: KContext, value: T) : - KFuncDecl1(ctx, "bv_neg_no_overflow", resultSort = ctx.mkBoolSort(), value) { +class KBvNegNoOverflowDecl internal constructor( + ctx: KContext, + value: T +) : KFuncDecl1( + ctx, + "bv_neg_no_overflow", + resultSort = ctx.mkBoolSort(), + value +) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg: KExpr): KApp> = - mkBvNegationNoOverflowExpr(arg) + override fun KContext.apply( + arg: KExpr + ): KApp> = mkBvNegationNoOverflowExpr(arg) } class KBvMulNoOverflowDecl internal constructor( @@ -678,14 +860,17 @@ class KBvMulNoOverflowDecl internal constructor( get() = listOf(isSigned) } -class KBvMulNoUnderflowDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2( - ctx, - "bv_mul_no_underflow", - resultSort = ctx.mkBoolSort(), - arg0Sort, - arg1Sort - ) { +class KBvMulNoUnderflowDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2( + ctx, + "bv_mul_no_underflow", + resultSort = ctx.mkBoolSort(), + arg0Sort, + arg1Sort +) { init { checkSortsAreTheSame(arg0Sort, arg1Sort) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/decl/KConstDecl.kt b/ksmt-core/src/main/kotlin/org/ksmt/decl/KConstDecl.kt index 37fb74f5d..78cb3e859 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/decl/KConstDecl.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/decl/KConstDecl.kt @@ -5,10 +5,16 @@ import org.ksmt.expr.KApp import org.ksmt.expr.KExpr import org.ksmt.sort.KSort -open class KConstDecl(ctx: KContext, name: String, sort: T) : KFuncDecl(ctx, name, sort, emptyList()) { +open class KConstDecl( + ctx: KContext, + name: String, + sort: T +) : KFuncDecl(ctx, name, sort, emptyList()) { fun apply() = apply(emptyList()) + override fun apply(args: List>): KApp { - require(args.isEmpty()) { "Constant has no arguments" } + require(args.isEmpty()) { "Constant must have no arguments" } + return ctx.mkConstApp(this@KConstDecl) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/decl/KFloatingPointDecl.kt b/ksmt-core/src/main/kotlin/org/ksmt/decl/KFloatingPointDecl.kt index 43f23ac1b..473b7fa3d 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/decl/KFloatingPointDecl.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/decl/KFloatingPointDecl.kt @@ -50,40 +50,46 @@ private fun constructNameForDeclaration( return "FP (sign $sign) ($exponentBits $binaryExponent) ($significandBits $binarySignificand)" } -class KFp16Decl internal constructor(ctx: KContext, val value: Float) : - KFpDecl( - ctx, - ctx.mkFp16Sort(), - value.booleanSignBit, - value.halfPrecisionSignificand, - value.getHalfPrecisionExponent(isBiased = false) - ) { +class KFp16Decl internal constructor( + ctx: KContext, + val value: Float +) : KFpDecl( + ctx, + ctx.mkFp16Sort(), + value.booleanSignBit, + value.halfPrecisionSignificand, + value.getHalfPrecisionExponent(isBiased = false) +) { override fun apply(args: List>): KApp = ctx.mkFp16(value) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KFp32Decl internal constructor(ctx: KContext, val value: Float) : - KFpDecl( - ctx, - ctx.mkFp32Sort(), - value.booleanSignBit, - value.significand, - value.getExponent(isBiased = false) - ) { +class KFp32Decl internal constructor( + ctx: KContext, + val value: Float +) : KFpDecl( + ctx, + ctx.mkFp32Sort(), + value.booleanSignBit, + value.significand, + value.getExponent(isBiased = false) +) { override fun apply(args: List>): KApp = ctx.mkFp32(value) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KFp64Decl internal constructor(ctx: KContext, val value: Double) : - KFpDecl( - ctx, - ctx.mkFp64Sort(), - value.booleanSignBit, - value.significand, - value.getExponent(isBiased = false) - ) { +class KFp64Decl internal constructor( + ctx: KContext, + val value: Double +) : KFpDecl( + ctx, + ctx.mkFp64Sort(), + value.booleanSignBit, + value.significand, + value.getExponent(isBiased = false) +) { override fun apply(args: List>): KApp = ctx.mkFp64(value) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) @@ -108,7 +114,13 @@ class KFpCustomSizeDecl internal constructor( significand: Long, exponent: Long, signBit: Boolean -) : KFpDecl(ctx, ctx.mkFpSort(exponentSize, significandSize), signBit, significand, exponent) { +) : KFpDecl( + ctx, + ctx.mkFpSort(exponentSize, significandSize), + signBit, + significand, + exponent +) { override fun apply(args: List>): KApp = ctx.mkFpCustomSize( sort.exponentBits, @@ -121,15 +133,19 @@ class KFpCustomSizeDecl internal constructor( override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KFpAbsDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "fp.abs", valueSort, valueSort) { +class KFpAbsDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "fp.abs", valueSort, valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = ctx.mkFpAbsExpr(arg) } -class KFpNegationDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "fp.neg", valueSort, valueSort) { +class KFpNegationDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "fp.neg", valueSort, valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = ctx.mkFpNegationExpr(arg) @@ -140,10 +156,21 @@ class KFpAddDecl internal constructor( roundingModeSort: KFpRoundingModeSort, arg0Sort: T, arg1Sort: T -) : KFuncDecl3(ctx, "fp.add", arg0Sort, roundingModeSort, arg0Sort, arg1Sort) { +) : KFuncDecl3( + ctx, + "fp.add", + arg0Sort, + roundingModeSort, + arg0Sort, + arg1Sort +) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr, arg2: KExpr): KApp = - ctx.mkFpAddExpr(arg0, arg1, arg2) + + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr, + arg2: KExpr + ): KApp = ctx.mkFpAddExpr(arg0, arg1, arg2) } class KFpSubDecl internal constructor( @@ -152,11 +179,20 @@ class KFpSubDecl internal constructor( arg0Sort: T, arg1Sort: T ) : KFuncDecl3( - ctx, "fp.sub", resultSort = arg0Sort, roundingModeSort, arg0Sort, arg1Sort + ctx, + "fp.sub", + resultSort = arg0Sort, + roundingModeSort, + arg0Sort, + arg1Sort ) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr, arg2: KExpr): KApp = - ctx.mkFpSubExpr(arg0, arg1, arg2) + + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr, + arg2: KExpr + ): KApp = ctx.mkFpSubExpr(arg0, arg1, arg2) } class KFpMulDecl internal constructor( @@ -179,21 +215,39 @@ class KFpDivDecl internal constructor( arg0Sort: T, arg1Sort: T ) : KFuncDecl3( - ctx, "fp.div", resultSort = arg0Sort, roundingModeSort, arg0Sort, arg1Sort + ctx, + "fp.div", + resultSort = arg0Sort, + roundingModeSort, + arg0Sort, + arg1Sort ) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr, arg2: KExpr): KApp = - ctx.mkFpDivExpr(arg0, arg1, arg2) + + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr, + arg2: KExpr + ): KApp = ctx.mkFpDivExpr(arg0, arg1, arg2) } class KFpFusedMulAddDecl internal constructor( ctx: KContext, roundingModeSort: KFpRoundingModeSort, - arg0Sort: T, arg1Sort: T, arg2Sort: T + arg0Sort: T, + arg1Sort: T, + arg2Sort: T ) : KFuncDecl4( - ctx, "fp.fma", resultSort = arg0Sort, roundingModeSort, arg0Sort, arg1Sort, arg2Sort + ctx, + "fp.fma", + resultSort = arg0Sort, + roundingModeSort, + arg0Sort, + arg1Sort, + arg2Sort ) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) + override fun KContext.apply( arg0: KExpr, arg1: KExpr, @@ -206,14 +260,26 @@ class KFpSqrtDecl internal constructor( ctx: KContext, roundingModeSort: KFpRoundingModeSort, valueSort: T -) : KFuncDecl2(ctx, "fp.sqrt", resultSort = valueSort, roundingModeSort, valueSort) { +) : KFuncDecl2( + ctx, + "fp.sqrt", + resultSort = valueSort, + roundingModeSort, + valueSort +) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = - ctx.mkFpSqrtExpr(arg0, arg1) + + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkFpSqrtExpr(arg0, arg1) } -class KFpRemDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "fp.rem", arg0Sort, arg0Sort, arg1Sort) { +class KFpRemDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "fp.rem", arg0Sort, arg0Sort, arg1Sort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = ctx.mkFpRemExpr(arg0, arg1) @@ -224,109 +290,166 @@ class KFpRoundToIntegralDecl internal constructor( roundingModeSort: KFpRoundingModeSort, valueSort: T ) : KFuncDecl2( - ctx, "fp.roundToIntegral", resultSort = valueSort, roundingModeSort, valueSort + ctx, + "fp.roundToIntegral", + resultSort = valueSort, + roundingModeSort, + valueSort ) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = - ctx.mkFpRoundToIntegralExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkFpRoundToIntegralExpr(arg0, arg1) } -class KFpMinDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "fp.min", arg0Sort, arg0Sort, arg1Sort) { +class KFpMinDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "fp.min", arg0Sort, arg0Sort, arg1Sort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = ctx.mkFpMinExpr(arg0, arg1) } -class KFpMaxDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "fp.max", arg0Sort, arg0Sort, arg1Sort) { +class KFpMaxDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "fp.max", arg0Sort, arg0Sort, arg1Sort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = ctx.mkFpMaxExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkFpMaxExpr(arg0, arg1) } -class KFpLessOrEqualDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "fp.leq", ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KFpLessOrEqualDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "fp.leq", ctx.mkBoolSort(), arg0Sort, arg1Sort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = - ctx.mkFpLessOrEqualExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkFpLessOrEqualExpr(arg0, arg1) } -class KFpLessDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "fp.lt", ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KFpLessDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "fp.lt", ctx.mkBoolSort(), arg0Sort, arg1Sort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = ctx.mkFpLessExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkFpLessExpr(arg0, arg1) } -class KFpGreaterOrEqualDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "fp.geq", ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KFpGreaterOrEqualDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "fp.geq", ctx.mkBoolSort(), arg0Sort, arg1Sort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = - ctx.mkFpGreaterOrEqualExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkFpGreaterOrEqualExpr(arg0, arg1) } -class KFpGreaterDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "fp.gt", ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KFpGreaterDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "fp.gt", ctx.mkBoolSort(), arg0Sort, arg1Sort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = ctx.mkFpGreaterExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkFpGreaterExpr(arg0, arg1) } -class KFpEqualDecl internal constructor(ctx: KContext, arg0Sort: T, arg1Sort: T) : - KFuncDecl2(ctx, "fp.eq", ctx.mkBoolSort(), arg0Sort, arg1Sort) { +class KFpEqualDecl internal constructor( + ctx: KContext, + arg0Sort: T, + arg1Sort: T +) : KFuncDecl2(ctx, "fp.eq", ctx.mkBoolSort(), arg0Sort, arg1Sort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = ctx.mkFpEqualExpr(arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkFpEqualExpr(arg0, arg1) } -class KFpIsNormalDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "fp.isNormal", ctx.mkBoolSort(), valueSort) { +class KFpIsNormalDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "fp.isNormal", ctx.mkBoolSort(), valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = ctx.mkFpIsNormalExpr(arg) } -class KFpIsSubnormalDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "fp.isSubnormal", ctx.mkBoolSort(), valueSort) { +class KFpIsSubnormalDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "fp.isSubnormal", ctx.mkBoolSort(), valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = ctx.mkFpIsSubnormalExpr(arg) } -class KFpIsZeroDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "fp.isZero", ctx.mkBoolSort(), valueSort) { +class KFpIsZeroDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "fp.isZero", ctx.mkBoolSort(), valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = ctx.mkFpIsZeroExpr(arg) } -class KFpIsInfiniteDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "fp.isInfinite", ctx.mkBoolSort(), valueSort) { +class KFpIsInfiniteDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "fp.isInfinite", ctx.mkBoolSort(), valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = ctx.mkFpIsInfiniteExpr(arg) } -class KFpIsNaNDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "fp.isNaN", ctx.mkBoolSort(), valueSort) { +class KFpIsNaNDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "fp.isNaN", ctx.mkBoolSort(), valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = ctx.mkFpIsNaNExpr(arg) } -class KFpIsNegativeDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "fp.isNegative", ctx.mkBoolSort(), valueSort) { +class KFpIsNegativeDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "fp.isNegative", ctx.mkBoolSort(), valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = ctx.mkFpIsNegativeExpr(arg) } -class KFpIsPositiveDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "fp.isPositive", ctx.mkBoolSort(), valueSort) { +class KFpIsPositiveDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "fp.isPositive", ctx.mkBoolSort(), valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = ctx.mkFpIsPositiveExpr(arg) @@ -347,24 +470,30 @@ class KFpToBvDecl internal constructor( ) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = - ctx.mkFpToBvExpr(arg0, arg1, bvSize, isSigned) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkFpToBvExpr(arg0, arg1, bvSize, isSigned) } -class KFpToRealDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1(ctx, "fp.to_real", ctx.mkRealSort(), valueSort) { +class KFpToRealDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1(ctx, "fp.to_real", ctx.mkRealSort(), valueSort) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = ctx.mkFpToRealExpr(arg) } -class KFpToIEEEBvDecl internal constructor(ctx: KContext, valueSort: T) : - KFuncDecl1( - ctx, - "fp.to_ieee_bv", - ctx.mkBvSort(valueSort.significandBits + valueSort.exponentBits), - valueSort - ) { +class KFpToIEEEBvDecl internal constructor( + ctx: KContext, + valueSort: T +) : KFuncDecl1( + ctx, + "fp.to_ieee_bv", + ctx.mkBvSort(valueSort.significandBits + valueSort.exponentBits), + valueSort +) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) override fun KContext.apply(arg: KExpr): KApp> = ctx.mkFpToIEEEBvExpr(arg) @@ -376,12 +505,21 @@ class KFpFromBvDecl internal constructor( signSort: KBv1Sort, expSort: KBvSort, significandSort: KBvSort -) : KFuncDecl3(ctx, "fp.to_fp", sort, signSort, expSort, significandSort) { - +) : KFuncDecl3( + ctx, + "fp.to_fp", + sort, + signSort, + expSort, + significandSort +) { override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) - override fun KContext.apply(arg0: KExpr, arg1: KExpr, arg2: KExpr): KApp = - ctx.mkFpFromBvExpr(arg0, arg1, arg2) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr, + arg2: KExpr + ): KApp = ctx.mkFpFromBvExpr(arg0, arg1, arg2) } abstract class KToFpDecl internal constructor( @@ -390,7 +528,6 @@ abstract class KToFpDecl internal constructor( roundingModeSort: KFpRoundingModeSort, valueSort: S ) : KFuncDecl2(ctx, "fp.to_fp", resultSort = sort, roundingModeSort, valueSort) { - override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } @@ -400,8 +537,10 @@ class KFpToFpDecl internal constructor( roundingModeSort: KFpRoundingModeSort, valueSort: KFpSort ) : KToFpDecl(ctx, sort, roundingModeSort, valueSort) { - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = - ctx.mkFpToFpExpr(sort, arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkFpToFpExpr(sort, arg0, arg1) } class KRealToFpDecl internal constructor( @@ -410,8 +549,10 @@ class KRealToFpDecl internal constructor( roundingModeSort: KFpRoundingModeSort, valueSort: KRealSort ) : KToFpDecl(ctx, sort, roundingModeSort, valueSort) { - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = - ctx.mkRealToFpExpr(sort, arg0, arg1) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkRealToFpExpr(sort, arg0, arg1) } class KBvToFpDecl internal constructor( @@ -419,8 +560,10 @@ class KBvToFpDecl internal constructor( sort: T, roundingModeSort: KFpRoundingModeSort, valueSort: KBvSort, - val signed: Boolean + val isSigned: Boolean ) : KToFpDecl(ctx, sort, roundingModeSort, valueSort) { - override fun KContext.apply(arg0: KExpr, arg1: KExpr): KApp = - ctx.mkBvToFpExpr(sort, arg0, arg1, signed) + override fun KContext.apply( + arg0: KExpr, + arg1: KExpr + ): KApp = ctx.mkBvToFpExpr(sort, arg0, arg1, isSigned) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/decl/KFpRoundingModeDecl.kt b/ksmt-core/src/main/kotlin/org/ksmt/decl/KFpRoundingModeDecl.kt index 95eec74bf..702cb8d4c 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/decl/KFpRoundingModeDecl.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/decl/KFpRoundingModeDecl.kt @@ -6,8 +6,10 @@ import org.ksmt.expr.KExpr import org.ksmt.expr.KFpRoundingMode import org.ksmt.sort.KFpRoundingModeSort -class KFpRoundingModeDecl(ctx: KContext, val value: KFpRoundingMode) : - KConstDecl(ctx, value.modeName, ctx.mkFpRoundingModeSort()) { +class KFpRoundingModeDecl( + ctx: KContext, + val value: KFpRoundingMode +) : KConstDecl(ctx, value.modeName, ctx.mkFpRoundingModeSort()) { override fun apply(args: List>): KApp = ctx.mkFpRoundingModeExpr(value) override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) diff --git a/ksmt-core/src/main/kotlin/org/ksmt/decl/KFuncDecl.kt b/ksmt-core/src/main/kotlin/org/ksmt/decl/KFuncDecl.kt index 824d1b94a..2be5977a4 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/decl/KFuncDecl.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/decl/KFuncDecl.kt @@ -24,7 +24,10 @@ open class KFuncDecl( append(" (") for ((i, sort) in argSorts.withIndex()) { - if (i > 0) append(" ") + if (i > 0) { + append(" ") + } + sort.print(this) } @@ -37,7 +40,9 @@ open class KFuncDecl( check(args.size == argSorts.size) { "${argSorts.size} arguments expected but ${args.size} provided" } + val providedSorts = args.map { it.sort } + check(providedSorts == argSorts) { "Arguments sort mismatch. Expected $argSorts but $providedSorts provided" } @@ -73,6 +78,7 @@ abstract class KFuncDecl2( override fun apply(args: List>): KApp = with(ctx) { checkArgSorts(args) val (arg0, arg1) = args + return apply(arg0 as KExpr, arg1 as KExpr) } } @@ -91,12 +97,13 @@ abstract class KFuncDecl3( override fun apply(args: List>): KApp = with(ctx) { checkArgSorts(args) val (arg0, arg1, arg2) = args + return apply(arg0 as KExpr, arg1 as KExpr, arg2 as KExpr) } } @Suppress("LongParameterList") -abstract class KFuncDecl4( +abstract class KFuncDecl4( ctx: KContext, name: String, resultSort: T, @@ -105,12 +112,18 @@ abstract class KFuncDecl4(ctx, name, resultSort, listOf(arg0Sort, arg1Sort, arg2Sort, arg3Sort)) { - abstract fun KContext.apply(arg0: KExpr, arg1: KExpr, arg2: KExpr, arg3: KExpr): KApp + abstract fun KContext.apply( + arg0: KExpr, + arg1: KExpr, + arg2: KExpr, + arg3: KExpr + ): KApp @Suppress("UNCHECKED_CAST") override fun apply(args: List>): KApp = with(ctx) { checkArgSorts(args) val (arg0, arg1, arg2, arg3) = args + return apply(arg0 as KExpr, arg1 as KExpr, arg2 as KExpr, arg3 as KExpr) } } @@ -131,9 +144,13 @@ abstract class KFuncDeclChain( builder.append('(') builder.append(name) builder.append(" (") + argSort.print(builder) + builder.append(" *) ") + sort.print(builder) + builder.append(" )") } @@ -143,6 +160,7 @@ abstract class KFuncDeclChain( check(providedSorts.all { it == argSort }) { "Arguments sort mismatch. Expected arguments of sort $argSort but $providedSorts provided" } + return applyChain(args as List>) } } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/decl/Real.kt b/ksmt-core/src/main/kotlin/org/ksmt/decl/Real.kt index f642b6dfa..7937249f2 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/decl/Real.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/decl/Real.kt @@ -7,20 +7,37 @@ import org.ksmt.sort.KBoolSort import org.ksmt.sort.KIntSort import org.ksmt.sort.KRealSort -class KRealToIntDecl internal constructor(ctx: KContext) : - KFuncDecl1(ctx, "realToInt", ctx.mkIntSort(), ctx.mkRealSort()) { +class KRealToIntDecl internal constructor( + ctx: KContext +) : KFuncDecl1( + ctx, + "realToInt", + ctx.mkIntSort(), + ctx.mkRealSort() +) { override fun KContext.apply(arg: KExpr): KApp> = mkRealToInt(arg) + override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KRealIsIntDecl internal constructor(ctx: KContext) : - KFuncDecl1(ctx, "realIsInt", ctx.mkBoolSort(), ctx.mkRealSort()) { +class KRealIsIntDecl internal constructor( + ctx: KContext +) : KFuncDecl1( + ctx, + "realIsInt", + ctx.mkBoolSort(), + ctx.mkRealSort() +) { override fun KContext.apply(arg: KExpr): KApp> = mkRealIsInt(arg) + override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } -class KRealNumDecl internal constructor(ctx: KContext, val value: String) : - KConstDecl(ctx, value, ctx.mkRealSort()) { +class KRealNumDecl internal constructor( + ctx: KContext, + val value: String +) : KConstDecl(ctx, value, ctx.mkRealSort()) { override fun apply(args: List>): KApp = ctx.mkRealNum(value) + override fun accept(visitor: KDeclVisitor): R = visitor.visit(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/Arith.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/Arith.kt index 2255b8de5..ff89233eb 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/Arith.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/Arith.kt @@ -11,7 +11,7 @@ import org.ksmt.decl.KArithMulDecl import org.ksmt.decl.KArithPowerDecl import org.ksmt.decl.KArithSubDecl import org.ksmt.decl.KArithUnaryMinusDecl -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.sort.KArithSort import org.ksmt.sort.KBoolSort @@ -24,8 +24,10 @@ class KAddArithExpr> internal constructor( } override fun sort(): T = with(ctx) { args.first().sort } + override fun decl(): KArithAddDecl = with(ctx) { mkArithAddDecl(sort) } - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KMulArithExpr> internal constructor( @@ -37,8 +39,10 @@ class KMulArithExpr> internal constructor( } override fun sort(): T = with(ctx) { args.first().sort } + override fun decl(): KArithMulDecl = with(ctx) { mkArithMulDecl(sort) } - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KSubArithExpr> internal constructor( @@ -50,8 +54,10 @@ class KSubArithExpr> internal constructor( } override fun sort(): T = with(ctx) { args.first().sort } + override fun decl(): KArithSubDecl = with(ctx) { mkArithSubDecl(sort) } - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KUnaryMinusArithExpr> internal constructor( @@ -59,11 +65,13 @@ class KUnaryMinusArithExpr> internal constructor( val arg: KExpr ) : KApp>(ctx) { override fun sort(): T = with(ctx) { arg.sort } + override fun decl(): KArithUnaryMinusDecl = with(ctx) { mkArithUnaryMinusDecl(sort) } + override val args: List> get() = listOf(arg) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KDivArithExpr> internal constructor( @@ -72,11 +80,13 @@ class KDivArithExpr> internal constructor( val rhs: KExpr ) : KApp>(ctx) { override fun sort(): T = with(ctx) { lhs.sort } + override fun decl(): KArithDivDecl = with(ctx) { mkArithDivDecl(sort) } + override val args: List> get() = listOf(lhs, rhs) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KPowerArithExpr> internal constructor( @@ -85,11 +95,13 @@ class KPowerArithExpr> internal constructor( val rhs: KExpr ) : KApp>(ctx) { override fun sort(): T = with(ctx) { lhs.sort } + override fun decl(): KArithPowerDecl = with(ctx) { mkArithPowerDecl(sort) } + override val args: List> get() = listOf(lhs, rhs) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KLtArithExpr> internal constructor( @@ -98,11 +110,13 @@ class KLtArithExpr> internal constructor( val rhs: KExpr ) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KArithLtDecl = with(ctx) { mkArithLtDecl(lhs.sort) } + override val args: List> get() = listOf(lhs, rhs) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KLeArithExpr> internal constructor( @@ -111,11 +125,13 @@ class KLeArithExpr> internal constructor( val rhs: KExpr ) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KArithLeDecl = with(ctx) { mkArithLeDecl(lhs.sort) } + override val args: List> get() = listOf(lhs, rhs) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KGtArithExpr> internal constructor( @@ -124,11 +140,13 @@ class KGtArithExpr> internal constructor( val rhs: KExpr ) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KArithGtDecl = with(ctx) { mkArithGtDecl(lhs.sort) } + override val args: List> get() = listOf(lhs, rhs) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KGeArithExpr> internal constructor( @@ -137,9 +155,11 @@ class KGeArithExpr> internal constructor( val rhs: KExpr ) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KArithGeDecl = with(ctx) { mkArithGeDecl(lhs.sort) } + override val args: List> get() = listOf(lhs, rhs) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/Array.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/Array.kt index 89426ac97..ee5e41478 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/Array.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/Array.kt @@ -4,7 +4,7 @@ import org.ksmt.KContext import org.ksmt.decl.KArrayConstDecl import org.ksmt.decl.KDecl import org.ksmt.decl.KFuncDecl -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.sort.KArraySort import org.ksmt.sort.KSort @@ -15,11 +15,13 @@ class KArrayStore internal constructor( val value: KExpr ) : KApp, KExpr<*>>(ctx) { override fun sort(): KArraySort = with(ctx) { array.sort } + override fun decl(): KDecl> = with(ctx) { mkArrayStoreDecl(array.sort) } + override val args: List> get() = listOf(array, index, value) - override fun accept(transformer: KTransformer): KExpr> = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr> = transformer.transform(this) } class KArraySelect internal constructor( @@ -28,11 +30,13 @@ class KArraySelect internal constructor( val index: KExpr ) : KApp>(ctx) { override fun sort(): R = with(ctx) { array.sort.range } + override fun decl(): KDecl = with(ctx) { mkArraySelectDecl(array.sort) } + override val args: List> get() = listOf(array, index) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KArrayConst internal constructor( @@ -41,11 +45,13 @@ class KArrayConst internal constructor( val value: KExpr ) : KApp, KExpr>(ctx) { override fun sort(): KArraySort = sort + override fun decl(): KArrayConstDecl = ctx.mkArrayConstDecl(sort) + override val args: List> get() = listOf(value) - override fun accept(transformer: KTransformer): KExpr> = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr> = transformer.transform(this) } class KFunctionAsArray internal constructor( @@ -63,12 +69,14 @@ class KFunctionAsArray internal constructor( } override fun sort(): KArraySort = with(ctx) { mkArraySort(domainSort, function.sort) } + override fun print(builder: StringBuilder): Unit = with(builder) { append("(asArray ") append(function.name) append(')') } - override fun accept(transformer: KTransformer): KExpr> = transformer.transform(this) + + override fun accept(transformer: KTransformerBase): KExpr> = transformer.transform(this) } /** Array lambda binding. @@ -81,15 +89,19 @@ class KArrayLambda internal constructor( val body: KExpr ) : KExpr>(ctx) { override fun sort(): KArraySort = with(ctx) { mkArraySort(indexVarDecl.sort, body.sort) } + override fun print(builder: StringBuilder): Unit = with(builder) { append("(lambda ((") append(indexVarDecl.name) append(' ') + indexVarDecl.sort.print(this) append(")) ") + body.print(this) + append(')') } - override fun accept(transformer: KTransformer): KExpr> = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr> = transformer.transform(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/Bool.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/Bool.kt index 2ac9b927d..7b56731c7 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/Bool.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/Bool.kt @@ -11,7 +11,7 @@ import org.ksmt.decl.KNotDecl import org.ksmt.decl.KOrDecl import org.ksmt.decl.KTrueDecl import org.ksmt.decl.KXorDecl -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.sort.KBoolSort import org.ksmt.sort.KSort @@ -20,8 +20,10 @@ class KAndExpr internal constructor( override val args: List> ) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KAndDecl = ctx.mkAndDecl() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KOrExpr internal constructor( @@ -29,8 +31,10 @@ class KOrExpr internal constructor( override val args: List> ) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KOrDecl = ctx.mkOrDecl() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KNotExpr internal constructor( @@ -38,11 +42,13 @@ class KNotExpr internal constructor( val arg: KExpr ) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KNotDecl = ctx.mkNotDecl() + override val args: List> get() = listOf(arg) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KImpliesExpr internal constructor( @@ -51,11 +57,13 @@ class KImpliesExpr internal constructor( val q: KExpr ) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KImpliesDecl = ctx.mkImpliesDecl() + override val args: List> get() = listOf(p, q) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KXorExpr internal constructor( @@ -64,11 +72,13 @@ class KXorExpr internal constructor( val b: KExpr ) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KXorDecl = ctx.mkXorDecl() + override val args: List> get() = listOf(a, b) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KEqExpr internal constructor( @@ -76,11 +86,13 @@ class KEqExpr internal constructor( val lhs: KExpr, val rhs: KExpr ) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KEqDecl = with(ctx) { mkEqDecl(lhs.sort) } + override val args: List> get() = listOf(lhs, rhs) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KDistinctExpr internal constructor( @@ -92,8 +104,10 @@ class KDistinctExpr internal constructor( } override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KDistinctDecl = with(ctx) { mkDistinctDecl(args.first().sort) } - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KIteExpr internal constructor( @@ -103,23 +117,31 @@ class KIteExpr internal constructor( val falseBranch: KExpr ) : KApp>(ctx) { override fun sort(): T = with(ctx) { trueBranch.sort } + override fun decl(): KIteDecl = with(ctx) { mkIteDecl(trueBranch.sort) } + override val args: List> get() = listOf(condition, trueBranch, falseBranch) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KTrue(ctx: KContext) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KTrueDecl = ctx.mkTrueDecl() + override val args = emptyList>() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFalse(ctx: KContext) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KFalseDecl = ctx.mkFalseDecl() + override val args = emptyList>() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/Integer.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/Integer.kt index 9555b2840..e647fe6ee 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/Integer.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/Integer.kt @@ -5,7 +5,7 @@ import org.ksmt.decl.KIntModDecl import org.ksmt.decl.KIntNumDecl import org.ksmt.decl.KIntRemDecl import org.ksmt.decl.KIntToRealDecl -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.sort.KIntSort import org.ksmt.sort.KRealSort import java.math.BigInteger @@ -16,11 +16,13 @@ class KModIntExpr internal constructor( val rhs: KExpr ) : KApp>(ctx) { override fun sort(): KIntSort = ctx.mkIntSort() + override fun decl(): KIntModDecl = ctx.mkIntModDecl() + override val args: List> get() = listOf(lhs, rhs) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KRemIntExpr internal constructor( @@ -29,11 +31,13 @@ class KRemIntExpr internal constructor( val rhs: KExpr ) : KApp>(ctx) { override fun sort(): KIntSort = ctx.mkIntSort() + override fun decl(): KIntRemDecl = ctx.mkIntRemDecl() + override val args: List> get() = listOf(lhs, rhs) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KToRealIntExpr internal constructor( @@ -41,11 +45,13 @@ class KToRealIntExpr internal constructor( val arg: KExpr ) : KApp>(ctx) { override fun sort(): KRealSort = ctx.mkRealSort() + override fun decl(): KIntToRealDecl = ctx.mkIntToRealDecl() + override val args: List> get() = listOf(arg) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } abstract class KIntNumExpr( @@ -53,7 +59,9 @@ abstract class KIntNumExpr( private val value: Number ) : KApp>(ctx) { override fun sort(): KIntSort = ctx.mkIntSort() + override fun decl(): KIntNumDecl = ctx.mkIntNumDecl("$value") + override val args = emptyList>() } @@ -61,19 +69,19 @@ class KInt32NumExpr internal constructor( ctx: KContext, val value: Int ) : KIntNumExpr(ctx, value) { - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KInt64NumExpr internal constructor( ctx: KContext, val value: Long ) : KIntNumExpr(ctx, value) { - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KIntBigNumExpr internal constructor( ctx: KContext, val value: BigInteger ) : KIntNumExpr(ctx, value) { - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/KApp.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/KApp.kt index 9367dc043..258316a81 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/KApp.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/KApp.kt @@ -2,24 +2,29 @@ package org.ksmt.expr import org.ksmt.KContext import org.ksmt.decl.KDecl -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.sort.KSort abstract class KApp> internal constructor(ctx: KContext) : KExpr(ctx) { abstract val args: List + abstract fun decl(): KDecl + override fun print(builder: StringBuilder): Unit = with(ctx) { with(builder) { if (args.isEmpty()) { append(decl.name) return } + append('(') append(decl.name) + for (arg in args) { append(' ') arg.print(this) } + append(')') } } @@ -31,12 +36,15 @@ open class KFunctionApp internal constructor( override val args: List> ) : KApp>(ctx) { override fun sort(): T = decl.sort + override fun decl(): KDecl = decl - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } -class KConst internal constructor(ctx: KContext, decl: KDecl) : - KFunctionApp(ctx, decl, args = emptyList()) { - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) +class KConst internal constructor( + ctx: KContext, + decl: KDecl +) : KFunctionApp(ctx, decl, args = emptyList()) { + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/KBitVecExprs.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/KBitVecExprs.kt index adc9eddd0..f0f3f250c 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/KBitVecExprs.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/KBitVecExprs.kt @@ -2,7 +2,7 @@ package org.ksmt.expr import org.ksmt.KContext import org.ksmt.decl.KDecl -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.sort.KBv1Sort import org.ksmt.sort.KBoolSort import org.ksmt.sort.KBv16Sort @@ -21,8 +21,11 @@ abstract class KBitVecValue( abstract val stringValue: String } -class KBitVec1Value internal constructor(ctx: KContext, val value: Boolean) : KBitVecValue(ctx) { - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) +class KBitVec1Value internal constructor( + ctx: KContext, + val value: Boolean +) : KBitVecValue(ctx) { + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) override val stringValue: String = if (value) "1" else "0" @@ -38,36 +41,44 @@ abstract class KBitVecNumberValue( override val stringValue: String = numberValue.toBinary() } -class KBitVec8Value internal constructor(ctx: KContext, byteValue: Byte) : - KBitVecNumberValue(ctx, byteValue) { - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) +class KBitVec8Value internal constructor( + ctx: KContext, + byteValue: Byte +) : KBitVecNumberValue(ctx, byteValue) { + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) override fun decl(): KDecl = ctx.mkBvDecl(numberValue) override fun sort(): KBv8Sort = ctx.mkBv8Sort() } -class KBitVec16Value internal constructor(ctx: KContext, shortValue: Short) : - KBitVecNumberValue(ctx, shortValue) { - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) +class KBitVec16Value internal constructor( + ctx: KContext, + shortValue: Short +) : KBitVecNumberValue(ctx, shortValue) { + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) override fun decl(): KDecl = ctx.mkBvDecl(numberValue) override fun sort(): KBv16Sort = ctx.mkBv16Sort() } -class KBitVec32Value internal constructor(ctx: KContext, intValue: Int) : - KBitVecNumberValue(ctx, intValue) { - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) +class KBitVec32Value internal constructor( + ctx: KContext, + intValue: Int +) : KBitVecNumberValue(ctx, intValue) { + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) override fun decl(): KDecl = ctx.mkBvDecl(numberValue) override fun sort(): KBv32Sort = ctx.mkBv32Sort() } -class KBitVec64Value internal constructor(ctx: KContext, longValue: Long) : - KBitVecNumberValue(ctx, longValue) { - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) +class KBitVec64Value internal constructor( + ctx: KContext, + longValue: Long +) : KBitVecNumberValue(ctx, longValue) { + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) override fun decl(): KDecl = ctx.mkBvDecl(numberValue) @@ -86,7 +97,7 @@ class KBitVecCustomValue internal constructor( } } - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) override val stringValue: String = binaryStringValue @@ -110,7 +121,7 @@ class KBvNotExpr internal constructor( override fun sort(): S = value.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -127,7 +138,7 @@ class KBvReductionAndExpr internal constructor( override fun sort(): KBv1Sort = ctx.mkBv1Sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -144,7 +155,7 @@ class KBvReductionOrExpr internal constructor( override fun sort(): KBv1Sort = ctx.mkBv1Sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -162,7 +173,7 @@ class KBvAndExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -180,7 +191,7 @@ class KBvOrExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -198,7 +209,7 @@ class KBvXorExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -216,7 +227,7 @@ class KBvNAndExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -234,7 +245,7 @@ class KBvNorExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -253,7 +264,7 @@ class KBvXNorExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -270,7 +281,7 @@ class KBvNegationExpr internal constructor( override fun sort(): S = value.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -288,7 +299,7 @@ class KBvAddExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -306,7 +317,7 @@ class KBvSubExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -324,7 +335,7 @@ class KBvMulExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -345,7 +356,7 @@ class KBvUnsignedDivExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -368,7 +379,7 @@ class KBvSignedDivExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -389,7 +400,7 @@ class KBvUnsignedRemExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -411,7 +422,7 @@ class KBvSignedRemExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -429,7 +440,7 @@ class KBvSignedModExpr internal constructor( override fun decl(): KDecl = ctx.mkBvSignedModDecl(arg0.sort(), arg1.sort()) override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -447,7 +458,7 @@ class KBvUnsignedLessExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -465,7 +476,7 @@ class KBvSignedLessExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -484,7 +495,7 @@ class KBvUnsignedLessOrEqualExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -503,7 +514,7 @@ class KBvSignedLessOrEqualExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -521,7 +532,7 @@ class KBvUnsignedGreaterOrEqualExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -539,7 +550,7 @@ class KBvSignedGreaterOrEqualExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -557,7 +568,7 @@ class KBvUnsignedGreaterExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -575,7 +586,7 @@ class KBvSignedGreaterExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -595,7 +606,7 @@ class KBvConcatExpr internal constructor( override fun sort(): KBvSort = decl().sort - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -617,28 +628,28 @@ class KBvExtractExpr internal constructor( override fun sort(): KBvSort = ctx.mkBvSort((high - low + 1).toUInt()) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** * Bit-vector sign extension. * - * Sign-extends the [value] to the (signed) equivalent bitvector of size `m + [i]`, + * Sign-extends the [value] to the (signed) equivalent bitvector of size `m + [extensionSize]`, * where `m` is the size of the [value]. */ class KBvSignExtensionExpr internal constructor( ctx: KContext, - val i: Int, + val extensionSize: Int, val value: KExpr ) : KApp>(ctx) { override val args: List> get() = listOf(value) - override fun decl(): KDecl = ctx.mkBvSignExtensionDecl(i, value.sort()) + override fun decl(): KDecl = ctx.mkBvSignExtensionDecl(extensionSize, value.sort()) - override fun sort(): KBvSort = ctx.mkBvSort(value.sort().sizeBits + i.toUInt()) + override fun sort(): KBvSort = ctx.mkBvSort(value.sort().sizeBits + extensionSize.toUInt()) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } @@ -646,21 +657,21 @@ class KBvSignExtensionExpr internal constructor( * Bit-vector zero extension. * * Extend the [value] with zeros to the (unsigned) equivalent bitvector - * of size `m + [i]`, where `m` is the size of the [value]. + * of size `m + [extensionSize]`, where `m` is the size of the [value]. */ class KBvZeroExtensionExpr internal constructor( ctx: KContext, - val i: Int, + val extensionSize: Int, val value: KExpr ) : KApp>(ctx) { override val args: List> get() = listOf(value) - override fun decl(): KDecl = ctx.mkBvZeroExtensionDecl(i, value.sort()) + override fun decl(): KDecl = ctx.mkBvZeroExtensionDecl(extensionSize, value.sort()) - override fun sort(): KBvSort = ctx.mkBvSort(value.sort().sizeBits + i.toUInt()) + override fun sort(): KBvSort = ctx.mkBvSort(value.sort().sizeBits + extensionSize.toUInt()) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } @@ -669,17 +680,17 @@ class KBvZeroExtensionExpr internal constructor( */ class KBvRepeatExpr internal constructor( ctx: KContext, - val i: Int, + val repeatNumber: Int, val value: KExpr ) : KApp>(ctx) { override val args: List> get() = listOf(value) - override fun decl(): KDecl = ctx.mkBvRepeatDecl(i, value.sort()) + override fun decl(): KDecl = ctx.mkBvRepeatDecl(repeatNumber, value.sort()) - override fun sort(): KBvSort = ctx.mkBvSort(value.sort().sizeBits * i.toUInt()) + override fun sort(): KBvSort = ctx.mkBvSort(value.sort().sizeBits * repeatNumber.toUInt()) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } @@ -700,7 +711,7 @@ class KBvShiftLeftExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } @@ -721,7 +732,7 @@ class KBvLogicalShiftRightExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } @@ -743,7 +754,7 @@ class KBvArithShiftRightExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } @@ -764,27 +775,27 @@ class KBvRotateLeftExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** * Rotate left. * - * Rotates bits of the [value] to the left [i] times. + * Rotates bits of the [value] to the left [rotationNumber] times. */ class KBvRotateLeftIndexedExpr internal constructor( ctx: KContext, - val i: Int, + val rotationNumber: Int, val value: KExpr ) : KApp>(ctx) { override val args: List> get() = listOf(value) - override fun decl(): KDecl = ctx.mkBvRotateLeftIndexedDecl(i, value.sort()) + override fun decl(): KDecl = ctx.mkBvRotateLeftIndexedDecl(rotationNumber, value.sort()) override fun sort(): S = value.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -804,27 +815,27 @@ class KBvRotateRightExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** * Rotate right. * - * Rotates bits of the [value] to the right [i] times. + * Rotates bits of the [value] to the right [rotationNumber] times. */ class KBvRotateRightIndexedExpr internal constructor( ctx: KContext, - val i: Int, + val rotationNumber: Int, val value: KExpr ) : KApp>(ctx) { override val args: List> get() = listOf(value) - override fun decl(): KDecl = ctx.mkBvRotateRightIndexedDecl(i, value.sort()) + override fun decl(): KDecl = ctx.mkBvRotateRightIndexedDecl(rotationNumber, value.sort()) override fun sort(): S = value.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -848,7 +859,7 @@ class KBv2IntExpr internal constructor( override fun sort(): KIntSort = ctx.mkIntSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KBvAddNoOverflowExpr internal constructor( @@ -864,7 +875,7 @@ class KBvAddNoOverflowExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KBvAddNoUnderflowExpr internal constructor( @@ -879,7 +890,7 @@ class KBvAddNoUnderflowExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KBvSubNoOverflowExpr internal constructor( @@ -894,7 +905,7 @@ class KBvSubNoOverflowExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KBvSubNoUnderflowExpr internal constructor( @@ -910,7 +921,7 @@ class KBvSubNoUnderflowExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KBvDivNoOverflowExpr internal constructor( @@ -925,7 +936,7 @@ class KBvDivNoOverflowExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KBvNegNoOverflowExpr internal constructor( @@ -939,7 +950,7 @@ class KBvNegNoOverflowExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KBvMulNoOverflowExpr internal constructor( @@ -955,7 +966,7 @@ class KBvMulNoOverflowExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KBvMulNoUnderflowExpr internal constructor( @@ -970,5 +981,5 @@ class KBvMulNoUnderflowExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/KExpr.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/KExpr.kt index dfca2aa72..7bc9109c7 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/KExpr.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/KExpr.kt @@ -2,14 +2,16 @@ package org.ksmt.expr import org.ksmt.KAst import org.ksmt.KContext -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.sort.KSort -abstract class KExpr(ctx: KContext): KAst(ctx) { +abstract class KExpr(ctx: KContext) : KAst(ctx) { abstract fun sort(): T - abstract fun accept(transformer: KTransformer): KExpr + + abstract fun accept(transformer: KTransformerBase): KExpr // Contexts guarantee that any two equivalent expressions will be the same kotlin object override fun equals(other: Any?): Boolean = this === other + override fun hashCode(): Int = System.identityHashCode(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/KFloatingPointExpr.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/KFloatingPointExpr.kt index 779519263..a2fc03146 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/KFloatingPointExpr.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/KFloatingPointExpr.kt @@ -2,7 +2,7 @@ package org.ksmt.expr import org.ksmt.KContext import org.ksmt.decl.KDecl -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.sort.KBoolSort import org.ksmt.sort.KBv1Sort import org.ksmt.sort.KBvSort @@ -41,14 +41,15 @@ abstract class KFpValue( * 0 00000000 00000000000000000000000 (1 8 23) * x x___xxxx xxxxxxxxxx_____________ (1 5 10) */ -class KFp16Value internal constructor(ctx: KContext, val value: Float) : - KFpValue( - ctx, - significand = with(ctx) { value.halfPrecisionSignificand.toBv(KFp16Sort.significandBits - 1u) }, - exponent = with(ctx) { value.getHalfPrecisionExponent(isBiased = false).toBv(KFp16Sort.exponentBits) }, - signBit = value.booleanSignBit - ) { - +class KFp16Value internal constructor( + ctx: KContext, + val value: Float +) : KFpValue( + ctx, + significand = with(ctx) { value.halfPrecisionSignificand.toBv(KFp16Sort.significandBits - 1u) }, + exponent = with(ctx) { value.getHalfPrecisionExponent(isBiased = false).toBv(KFp16Sort.exponentBits) }, + signBit = value.booleanSignBit +) { init { // TODO add checks for the bounds } @@ -57,35 +58,39 @@ class KFp16Value internal constructor(ctx: KContext, val value: Float) : override fun sort(): KFp16Sort = ctx.mkFp16Sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } -class KFp32Value internal constructor(ctx: KContext, val value: Float) : - KFpValue( - ctx, - significand = with(ctx) { value.significand.toBv(KFp32Sort.significandBits - 1u) }, - exponent = with(ctx) { value.getExponent(isBiased = false).toBv(KFp32Sort.exponentBits) }, - signBit = value.booleanSignBit - ) { +class KFp32Value internal constructor( + ctx: KContext, + val value: Float +) : KFpValue( + ctx, + significand = with(ctx) { value.significand.toBv(KFp32Sort.significandBits - 1u) }, + exponent = with(ctx) { value.getExponent(isBiased = false).toBv(KFp32Sort.exponentBits) }, + signBit = value.booleanSignBit +) { override fun decl(): KDecl = ctx.mkFp32Decl(value) override fun sort(): KFp32Sort = ctx.mkFp32Sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } -class KFp64Value internal constructor(ctx: KContext, val value: Double) : - KFpValue( - ctx, - significand = with(ctx) { value.significand.toBv(KFp64Sort.significandBits - 1u) }, - exponent = with(ctx) { value.getExponent(isBiased = false).toBv(KFp64Sort.exponentBits) }, - signBit = value.booleanSignBit - ) { +class KFp64Value internal constructor( + ctx: KContext, + val value: Double +) : KFpValue( + ctx, + significand = with(ctx) { value.significand.toBv(KFp64Sort.significandBits - 1u) }, + exponent = with(ctx) { value.getExponent(isBiased = false).toBv(KFp64Sort.exponentBits) }, + signBit = value.booleanSignBit +) { override fun decl(): KDecl = ctx.mkFp64Decl(value) override fun sort(): KFp64Sort = ctx.mkFp64Sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -109,7 +114,7 @@ class KFp128Value internal constructor( override fun sort(): KFp128Sort = ctx.mkFp128Sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -138,12 +143,17 @@ class KFpCustomSizeValue internal constructor( } } - override fun decl(): KDecl = - ctx.mkFpCustomSizeDecl(significandSize, exponentSize, significandValue, exponentValue, signBit) + override fun decl(): KDecl = ctx.mkFpCustomSizeDecl( + significandSize, + exponentSize, + significandValue, + exponentValue, + signBit + ) override fun sort(): KFpSort = ctx.mkFpSort(exponentSize, significandSize) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpAbsExpr internal constructor( @@ -157,7 +167,7 @@ class KFpAbsExpr internal constructor( override fun sort(): S = value.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } /** @@ -174,7 +184,7 @@ class KFpNegationExpr internal constructor( override fun sort(): S = value.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } // TODO Can they have different sorts? @@ -191,7 +201,7 @@ class KFpAddExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpSubExpr internal constructor( @@ -207,7 +217,7 @@ class KFpSubExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpMulExpr internal constructor( @@ -219,11 +229,11 @@ class KFpMulExpr internal constructor( override val args: List> get() = listOf(roundingMode, arg0, arg1) - override fun decl(): KDecl = with(ctx) { mkFpMulDecl(roundingMode.sort, arg0.sort, arg1.sort) } + override fun decl(): KDecl = with(ctx) { mkFpMulDecl(roundingMode.sort, arg0.sort, arg1.sort) } override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpDivExpr internal constructor( @@ -239,7 +249,7 @@ class KFpDivExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpFusedMulAddExpr internal constructor( @@ -263,7 +273,7 @@ class KFpFusedMulAddExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } @@ -279,7 +289,7 @@ class KFpSqrtExpr internal constructor( override fun sort(): S = value.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } @@ -295,7 +305,7 @@ class KFpRemExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpRoundToIntegralExpr internal constructor( @@ -310,7 +320,7 @@ class KFpRoundToIntegralExpr internal constructor( override fun sort(): S = value.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } @@ -326,7 +336,7 @@ class KFpMinExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpMaxExpr internal constructor( @@ -341,7 +351,7 @@ class KFpMaxExpr internal constructor( override fun sort(): S = arg0.sort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpLessOrEqualExpr internal constructor( @@ -356,7 +366,7 @@ class KFpLessOrEqualExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpLessExpr internal constructor( @@ -371,7 +381,7 @@ class KFpLessExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpGreaterOrEqualExpr internal constructor( @@ -386,7 +396,7 @@ class KFpGreaterOrEqualExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpGreaterExpr internal constructor( @@ -401,7 +411,7 @@ class KFpGreaterExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpEqualExpr internal constructor( @@ -416,7 +426,7 @@ class KFpEqualExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpIsNormalExpr internal constructor( @@ -430,7 +440,7 @@ class KFpIsNormalExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpIsSubnormalExpr internal constructor( @@ -444,7 +454,7 @@ class KFpIsSubnormalExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpIsZeroExpr internal constructor( @@ -458,7 +468,7 @@ class KFpIsZeroExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpIsInfiniteExpr internal constructor( @@ -472,7 +482,7 @@ class KFpIsInfiniteExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpIsNaNExpr internal constructor( @@ -486,7 +496,7 @@ class KFpIsNaNExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpIsNegativeExpr internal constructor( @@ -500,7 +510,7 @@ class KFpIsNegativeExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpIsPositiveExpr internal constructor( @@ -514,7 +524,7 @@ class KFpIsPositiveExpr internal constructor( override fun sort(): KBoolSort = ctx.mkBoolSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } // TODO mkFpToFp ??? @@ -529,11 +539,13 @@ class KFpToBvExpr internal constructor( override val args: List> get() = listOf(roundingMode, value) - override fun decl(): KDecl = with(ctx) { mkFpToBvDecl(roundingMode.sort, value.sort, bvSize, isSigned) } + override fun decl(): KDecl = with(ctx) { + mkFpToBvDecl(roundingMode.sort, value.sort, bvSize, isSigned) + } override fun sort(): KBvSort = decl().sort - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } @@ -548,7 +560,7 @@ class KFpToRealExpr internal constructor( override fun sort(): KRealSort = ctx.mkRealSort() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpToIEEEBvExpr internal constructor( @@ -562,7 +574,7 @@ class KFpToIEEEBvExpr internal constructor( override fun sort(): KBvSort = decl().sort - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpFromBvExpr internal constructor( @@ -581,7 +593,7 @@ class KFpFromBvExpr internal constructor( override fun sort(): S = sort - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KFpToFpExpr internal constructor( @@ -599,7 +611,7 @@ class KFpToFpExpr internal constructor( override fun sort(): S = sort - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KRealToFpExpr internal constructor( @@ -617,7 +629,7 @@ class KRealToFpExpr internal constructor( override fun sort(): S = sort - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KBvToFpExpr internal constructor( @@ -636,5 +648,5 @@ class KBvToFpExpr internal constructor( override fun sort(): S = sort - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/KFpRoundingMode.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/KFpRoundingMode.kt index c764f6803..99530a7ab 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/KFpRoundingMode.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/KFpRoundingMode.kt @@ -2,7 +2,7 @@ package org.ksmt.expr import org.ksmt.KContext import org.ksmt.decl.KDecl -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.sort.KFpRoundingModeSort enum class KFpRoundingMode(val modeName: String) { @@ -13,7 +13,10 @@ enum class KFpRoundingMode(val modeName: String) { RoundTowardZero("RoundTowardZero") } -class KFpRoundingModeExpr(ctx: KContext, val value: KFpRoundingMode): KApp>(ctx) { +class KFpRoundingModeExpr( + ctx: KContext, + val value: KFpRoundingMode +) : KApp>(ctx) { override val args: List> get() = emptyList() @@ -21,5 +24,5 @@ class KFpRoundingModeExpr(ctx: KContext, val value: KFpRoundingMode): KApp = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/KQuantifier.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/KQuantifier.kt index 942beb135..a84e5c45e 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/KQuantifier.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/KQuantifier.kt @@ -12,6 +12,7 @@ abstract class KQuantifier( override fun sort(): KBoolSort = ctx.mkBoolSort() abstract fun printQuantifierName(): String + override fun print(builder: StringBuilder): Unit = with(builder) { append('(') append(printQuantifierName()) diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/Quantifier.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/Quantifier.kt index 13b8df561..6e6de2fdc 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/Quantifier.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/Quantifier.kt @@ -2,7 +2,7 @@ package org.ksmt.expr import org.ksmt.KContext import org.ksmt.decl.KDecl -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.sort.KBoolSort class KExistentialQuantifier internal constructor( @@ -10,7 +10,8 @@ class KExistentialQuantifier internal constructor( body: KExpr, bounds: List> ) : KQuantifier(ctx, body, bounds) { - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) + override fun printQuantifierName(): String = "exists" } @@ -19,6 +20,7 @@ class KUniversalQuantifier internal constructor( body: KExpr, bounds: List> ) : KQuantifier(ctx, body, bounds) { - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) + override fun printQuantifierName(): String = "forall" } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/Real.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/Real.kt index 1e70b29ab..4bfe884e3 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/Real.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/Real.kt @@ -4,7 +4,7 @@ import org.ksmt.KContext import org.ksmt.decl.KRealIsIntDecl import org.ksmt.decl.KRealNumDecl import org.ksmt.decl.KRealToIntDecl -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.sort.KBoolSort import org.ksmt.sort.KIntSort import org.ksmt.sort.KRealSort @@ -14,11 +14,13 @@ class KToIntRealExpr internal constructor( val arg: KExpr ) : KApp>(ctx) { override fun sort(): KIntSort = ctx.mkIntSort() + override fun decl(): KRealToIntDecl = ctx.mkRealToIntDecl() + override val args: List> get() = listOf(arg) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KIsIntRealExpr internal constructor( @@ -26,11 +28,13 @@ class KIsIntRealExpr internal constructor( val arg: KExpr ) : KApp>(ctx) { override fun sort(): KBoolSort = ctx.mkBoolSort() + override fun decl(): KRealIsIntDecl = ctx.mkRealIsIntDecl() + override val args: List> get() = listOf(arg) - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } class KRealNumExpr internal constructor( @@ -39,7 +43,10 @@ class KRealNumExpr internal constructor( val denominator: KIntNumExpr ) : KApp>(ctx) { override fun sort(): KRealSort = ctx.mkRealSort() + override fun decl(): KRealNumDecl = ctx.mkRealNumDecl("$numerator/$denominator") + override val args = emptyList>() - override fun accept(transformer: KTransformer): KExpr = transformer.transform(this) + + override fun accept(transformer: KTransformerBase): KExpr = transformer.transform(this) } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/transformer/KNonRecursiveTransformer.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/transformer/KNonRecursiveTransformer.kt index d3e6dd504..8d98dd421 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/transformer/KNonRecursiveTransformer.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/transformer/KNonRecursiveTransformer.kt @@ -20,14 +20,17 @@ abstract class KNonRecursiveTransformer(override val ctx: KContext) : KTransform * */ fun apply(rootExpr: KExpr): KExpr { exprStack.add(rootExpr) + while (exprStack.isNotEmpty()) { val expr = exprStack.removeLast() exprWasTransformed = true val transformedExpr = expr.accept(this) + if (exprWasTransformed) { transformed[expr] = transformedExpr } } + return transformedExpr(rootExpr) ?: error("expr was not properly transformed: $rootExpr") } @@ -59,27 +62,38 @@ abstract class KNonRecursiveTransformer(override val ctx: KContext) : KTransform override fun transformApp(expr: KApp): KExpr = transformAppAfterArgsTransformed(expr as KApp>) { transformedArgs -> if (transformedArgs == expr.args) return transformExpr(expr) + val transformedApp = with(ctx) { mkApp(expr.decl, transformedArgs) } + return transformExpr(transformedApp) } - override fun transform(expr: KArrayLambda): KExpr> = - transformExprAfterTransformed(expr, listOf(expr.body)) { transformedBody -> - with(ctx) { - val body = transformedBody.single() - if (body == expr.body) return transformExpr(expr) - return transformExpr(mkArrayLambda(expr.indexVarDecl, body)) + override fun transform( + expr: KArrayLambda + ): KExpr> = transformExprAfterTransformed(expr, listOf(expr.body)) { transformedBody -> + with(ctx) { + val body = transformedBody.single() + + return if (body == expr.body) { + transformExpr(expr) + } else { + transformExpr(mkArrayLambda(expr.indexVarDecl, body)) } } + } override fun transform(expr: KExistentialQuantifier): KExpr = transformExprAfterTransformed(expr, listOf(expr.body)) { transformedBody -> with(ctx) { val body = transformedBody.single() - if (body == expr.body) return transformExpr(expr) - return transformExpr(mkExistentialQuantifier(body, expr.bounds)) + + return if (body == expr.body) { + transformExpr(expr) + } else { + transformExpr(mkExistentialQuantifier(body, expr.bounds)) + } } } @@ -87,8 +101,12 @@ abstract class KNonRecursiveTransformer(override val ctx: KContext) : KTransform transformExprAfterTransformed(expr, listOf(expr.body)) { transformedBody -> with(ctx) { val body = transformedBody.single() - if (body == expr.body) return transformExpr(expr) - return transformExpr(mkUniversalQuantifier(body, expr.bounds)) + + return if (body == expr.body) { + transformExpr(expr) + } else { + transformExpr(mkUniversalQuantifier(body, expr.bounds)) + } } } @@ -115,8 +133,10 @@ abstract class KNonRecursiveTransformer(override val ctx: KContext) : KTransform ): KExpr { val transformedDependencies = mutableListOf>() val notTransformedDependencies = mutableListOf>() + for (dependency in dependencies) { val transformedDependency = transformedExpr(dependency) + if (transformedDependency != null) { transformedDependencies += transformedDependency continue @@ -124,11 +144,14 @@ abstract class KNonRecursiveTransformer(override val ctx: KContext) : KTransform notTransformedDependencies += dependency } } + if (notTransformedDependencies.isNotEmpty()) { expr.transformAfter(notTransformedDependencies) markExpressionAsNotTransformed() + return expr } + return transformer(transformedDependencies) } } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/transformer/KTransformer.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/transformer/KTransformer.kt index 1d96693e6..a1baa4915 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/expr/transformer/KTransformer.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/transformer/KTransformer.kt @@ -154,182 +154,201 @@ import org.ksmt.sort.KRealSort import org.ksmt.sort.KSort -interface KTransformer { +interface KTransformer : KTransformerBase { val ctx: KContext - fun transform(expr: KExpr<*>): Any = error("transformer is not implemented for expr $expr") + + override fun transform(expr: KExpr<*>): Any = error("transformer is not implemented for expr $expr") + fun transformExpr(expr: KExpr): KExpr = expr // function transformers - fun transform(expr: KFunctionApp): KExpr = transformApp(expr) - fun transform(expr: KConst): KExpr = transform(expr as KFunctionApp) + override fun transform(expr: KFunctionApp): KExpr = transformApp(expr) + override fun transform(expr: KConst): KExpr = transform(expr as KFunctionApp) fun transformApp(expr: KApp): KExpr = with(ctx) { val args = expr.args.map { it.accept(this@KTransformer) } - if (args == expr.args) return transformExpr(expr) - return transformExpr(mkApp(expr.decl, args)) + + return if (args == expr.args) { + transformExpr(expr) + } else { + transformExpr(mkApp(expr.decl, args)) + } } // bool transformers - fun transform(expr: KAndExpr): KExpr = transformApp(expr) - fun transform(expr: KOrExpr): KExpr = transformApp(expr) - fun transform(expr: KNotExpr): KExpr = transformApp(expr) - fun transform(expr: KImpliesExpr): KExpr = transformApp(expr) - fun transform(expr: KXorExpr): KExpr = transformApp(expr) - fun transform(expr: KTrue): KExpr = transformApp(expr) - fun transform(expr: KFalse): KExpr = transformApp(expr) - fun transform(expr: KEqExpr): KExpr = transformApp(expr) - fun transform(expr: KDistinctExpr): KExpr = transformApp(expr) - fun transform(expr: KIteExpr): KExpr = transformApp(expr) + override fun transform(expr: KAndExpr): KExpr = transformApp(expr) + override fun transform(expr: KOrExpr): KExpr = transformApp(expr) + override fun transform(expr: KNotExpr): KExpr = transformApp(expr) + override fun transform(expr: KImpliesExpr): KExpr = transformApp(expr) + override fun transform(expr: KXorExpr): KExpr = transformApp(expr) + override fun transform(expr: KTrue): KExpr = transformApp(expr) + override fun transform(expr: KFalse): KExpr = transformApp(expr) + override fun transform(expr: KEqExpr): KExpr = transformApp(expr) + override fun transform(expr: KDistinctExpr): KExpr = transformApp(expr) + override fun transform(expr: KIteExpr): KExpr = transformApp(expr) // bit-vec transformers fun transformBitVecValue(expr: KBitVecValue): KExpr = transformApp(expr) - fun transform(expr: KBitVec1Value): KExpr = transformBitVecValue(expr) - fun transform(expr: KBitVec8Value): KExpr = transformBitVecValue(expr) - fun transform(expr: KBitVec16Value): KExpr = transformBitVecValue(expr) - fun transform(expr: KBitVec32Value): KExpr = transformBitVecValue(expr) - fun transform(expr: KBitVec64Value): KExpr = transformBitVecValue(expr) - fun transform(expr: KBitVecCustomValue): KExpr = transformBitVecValue(expr) + override fun transform(expr: KBitVec1Value): KExpr = transformBitVecValue(expr) + override fun transform(expr: KBitVec8Value): KExpr = transformBitVecValue(expr) + override fun transform(expr: KBitVec16Value): KExpr = transformBitVecValue(expr) + override fun transform(expr: KBitVec32Value): KExpr = transformBitVecValue(expr) + override fun transform(expr: KBitVec64Value): KExpr = transformBitVecValue(expr) + override fun transform(expr: KBitVecCustomValue): KExpr = transformBitVecValue(expr) // bit-vec expressions transformers - fun transform(expr: KBvNotExpr): KExpr = transformApp(expr) - fun transform(expr: KBvReductionAndExpr): KExpr = transformApp(expr) - fun transform(expr: KBvReductionOrExpr): KExpr = transformApp(expr) - fun transform(expr: KBvAndExpr): KExpr = transformApp(expr) - fun transform(expr: KBvOrExpr): KExpr = transformApp(expr) - fun transform(expr: KBvXorExpr): KExpr = transformApp(expr) - fun transform(expr: KBvNAndExpr): KExpr = transformApp(expr) - fun transform(expr: KBvNorExpr): KExpr = transformApp(expr) - fun transform(expr: KBvXNorExpr): KExpr = transformApp(expr) - fun transform(expr: KBvNegationExpr): KExpr = transformApp(expr) - fun transform(expr: KBvAddExpr): KExpr = transformApp(expr) - fun transform(expr: KBvSubExpr): KExpr = transformApp(expr) - fun transform(expr: KBvMulExpr): KExpr = transformApp(expr) - fun transform(expr: KBvUnsignedDivExpr): KExpr = transformApp(expr) - fun transform(expr: KBvSignedDivExpr): KExpr = transformApp(expr) - fun transform(expr: KBvUnsignedRemExpr): KExpr = transformApp(expr) - fun transform(expr: KBvSignedRemExpr): KExpr = transformApp(expr) - fun transform(expr: KBvSignedModExpr): KExpr = transformApp(expr) - fun transform(expr: KBvUnsignedLessExpr): KExpr = transformApp(expr) - fun transform(expr: KBvSignedLessExpr): KExpr = transformApp(expr) - fun transform(expr: KBvUnsignedLessOrEqualExpr): KExpr = transformApp(expr) - fun transform(expr: KBvSignedLessOrEqualExpr): KExpr = transformApp(expr) - fun transform(expr: KBvUnsignedGreaterOrEqualExpr): KExpr = transformApp(expr) - fun transform(expr: KBvSignedGreaterOrEqualExpr): KExpr = transformApp(expr) - fun transform(expr: KBvUnsignedGreaterExpr): KExpr = transformApp(expr) - fun transform(expr: KBvSignedGreaterExpr): KExpr = transformApp(expr) - fun transform(expr: KBvConcatExpr): KExpr = transformApp(expr) - fun transform(expr: KBvExtractExpr): KExpr = transformApp(expr) - fun transform(expr: KBvSignExtensionExpr): KExpr = transformApp(expr) - fun transform(expr: KBvZeroExtensionExpr): KExpr = transformApp(expr) - fun transform(expr: KBvRepeatExpr): KExpr = transformApp(expr) - fun transform(expr: KBvShiftLeftExpr): KExpr = transformApp(expr) - fun transform(expr: KBvLogicalShiftRightExpr): KExpr = transformApp(expr) - fun transform(expr: KBvArithShiftRightExpr): KExpr = transformApp(expr) - fun transform(expr: KBvRotateLeftExpr): KExpr = transformApp(expr) - fun transform(expr: KBvRotateLeftIndexedExpr): KExpr = transformApp(expr) - fun transform(expr: KBvRotateRightExpr): KExpr = transformApp(expr) - fun transform(expr: KBvRotateRightIndexedExpr): KExpr = transformApp(expr) - fun transform(expr: KBv2IntExpr): KExpr = transformApp(expr) - fun transform(expr: KBvAddNoOverflowExpr): KExpr = transformApp(expr) - fun transform(expr: KBvAddNoUnderflowExpr): KExpr = transformApp(expr) - fun transform(expr: KBvSubNoOverflowExpr): KExpr = transformApp(expr) - fun transform(expr: KBvSubNoUnderflowExpr): KExpr = transformApp(expr) - fun transform(expr: KBvDivNoOverflowExpr): KExpr = transformApp(expr) - fun transform(expr: KBvNegNoOverflowExpr): KExpr = transformApp(expr) - fun transform(expr: KBvMulNoOverflowExpr): KExpr = transformApp(expr) - fun transform(expr: KBvMulNoUnderflowExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvNotExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvReductionAndExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvReductionOrExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvAndExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvOrExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvXorExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvNAndExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvNorExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvXNorExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvNegationExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvAddExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvSubExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvMulExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvUnsignedDivExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvSignedDivExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvUnsignedRemExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvSignedRemExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvSignedModExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvUnsignedLessExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvSignedLessExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvUnsignedLessOrEqualExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvSignedLessOrEqualExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvUnsignedGreaterOrEqualExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvSignedGreaterOrEqualExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvUnsignedGreaterExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvSignedGreaterExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvConcatExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvExtractExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvSignExtensionExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvZeroExtensionExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvRepeatExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvShiftLeftExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvLogicalShiftRightExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvArithShiftRightExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvRotateLeftExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvRotateLeftIndexedExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvRotateRightExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvRotateRightIndexedExpr): KExpr = transformApp(expr) + override fun transform(expr: KBv2IntExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvAddNoOverflowExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvAddNoUnderflowExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvSubNoOverflowExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvSubNoUnderflowExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvDivNoOverflowExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvNegNoOverflowExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvMulNoOverflowExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvMulNoUnderflowExpr): KExpr = transformApp(expr) // fp value transformers fun transformFpValue(expr: KFpValue): KExpr = transformApp(expr) - fun transform(expr: KFp16Value): KExpr = transformFpValue(expr) - fun transform(expr: KFp32Value): KExpr = transformFpValue(expr) - fun transform(expr: KFp64Value): KExpr = transformFpValue(expr) - fun transform(expr: KFp128Value): KExpr = transformFpValue(expr) - fun transform(expr: KFpCustomSizeValue): KExpr = transformFpValue(expr) + override fun transform(expr: KFp16Value): KExpr = transformFpValue(expr) + override fun transform(expr: KFp32Value): KExpr = transformFpValue(expr) + override fun transform(expr: KFp64Value): KExpr = transformFpValue(expr) + override fun transform(expr: KFp128Value): KExpr = transformFpValue(expr) + override fun transform(expr: KFpCustomSizeValue): KExpr = transformFpValue(expr) // fp rounding mode - fun transform(expr: KFpRoundingModeExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpRoundingModeExpr): KExpr = transformApp(expr) // fp operations tranformation - fun transform(expr: KFpAbsExpr): KExpr = transformApp(expr) - fun transform(expr: KFpNegationExpr): KExpr = transformApp(expr) - fun transform(expr: KFpAddExpr): KExpr = transformApp(expr) - fun transform(expr: KFpSubExpr): KExpr = transformApp(expr) - fun transform(expr: KFpMulExpr): KExpr = transformApp(expr) - fun transform(expr: KFpDivExpr): KExpr = transformApp(expr) - fun transform(expr: KFpFusedMulAddExpr): KExpr = transformApp(expr) - fun transform(expr: KFpSqrtExpr): KExpr = transformApp(expr) - fun transform(expr: KFpRemExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpAbsExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpNegationExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpAddExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpSubExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpMulExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpDivExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpFusedMulAddExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpSqrtExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpRemExpr): KExpr = transformApp(expr) + @Suppress("MaxLineLength") - fun transform(expr: KFpRoundToIntegralExpr): KExpr = transformApp(expr) - fun transform(expr: KFpMinExpr): KExpr = transformApp(expr) - fun transform(expr: KFpMaxExpr): KExpr = transformApp(expr) - fun transform(expr: KFpLessOrEqualExpr): KExpr = transformApp(expr) - fun transform(expr: KFpLessExpr): KExpr = transformApp(expr) - fun transform(expr: KFpGreaterOrEqualExpr): KExpr = transformApp(expr) - fun transform(expr: KFpGreaterExpr): KExpr = transformApp(expr) - fun transform(expr: KFpEqualExpr): KExpr = transformApp(expr) - fun transform(expr: KFpIsNormalExpr): KExpr = transformApp(expr) - fun transform(expr: KFpIsSubnormalExpr): KExpr = transformApp(expr) - fun transform(expr: KFpIsZeroExpr): KExpr = transformApp(expr) - fun transform(expr: KFpIsInfiniteExpr): KExpr = transformApp(expr) - fun transform(expr: KFpIsNaNExpr): KExpr = transformApp(expr) - fun transform(expr: KFpIsNegativeExpr): KExpr = transformApp(expr) - fun transform(expr: KFpIsPositiveExpr): KExpr = transformApp(expr) - fun transform(expr: KFpToBvExpr): KExpr = transformApp(expr) - fun transform(expr: KFpToRealExpr): KExpr = transformApp(expr) - fun transform(expr: KFpToIEEEBvExpr): KExpr = transformApp(expr) - fun transform(expr: KFpFromBvExpr): KExpr = transformApp(expr) - fun transform(expr: KFpToFpExpr): KExpr = transformApp(expr) - fun transform(expr: KRealToFpExpr): KExpr = transformApp(expr) - fun transform(expr: KBvToFpExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpRoundToIntegralExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpMinExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpMaxExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpLessOrEqualExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpLessExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpGreaterOrEqualExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpGreaterExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpEqualExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpIsNormalExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpIsSubnormalExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpIsZeroExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpIsInfiniteExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpIsNaNExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpIsNegativeExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpIsPositiveExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpToBvExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpToRealExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpToIEEEBvExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpFromBvExpr): KExpr = transformApp(expr) + override fun transform(expr: KFpToFpExpr): KExpr = transformApp(expr) + override fun transform(expr: KRealToFpExpr): KExpr = transformApp(expr) + override fun transform(expr: KBvToFpExpr): KExpr = transformApp(expr) // array transformers - fun transform(expr: KArrayStore): KExpr> = transformApp(expr) - fun transform(expr: KArraySelect): KExpr = transformApp(expr) - fun transform(expr: KArrayConst): KExpr> = transformApp(expr) - fun transform(expr: KFunctionAsArray): KExpr> = transformExpr(expr) - fun transform(expr: KArrayLambda): KExpr> = with(ctx) { + override fun transform(expr: KArrayStore): KExpr> = transformApp(expr) + override fun transform(expr: KArraySelect): KExpr = transformApp(expr) + override fun transform(expr: KArrayConst): KExpr> = transformApp(expr) + + override fun transform(expr: KFunctionAsArray): KExpr> = + transformExpr(expr) + + override fun transform(expr: KArrayLambda): KExpr> = with(ctx) { val body = expr.body.accept(this@KTransformer) if (body == expr.body) return transformExpr(expr) return transformExpr(mkArrayLambda(expr.indexVarDecl, body)) } // arith transformers - fun > transform(expr: KAddArithExpr): KExpr = transformApp(expr) - fun > transform(expr: KMulArithExpr): KExpr = transformApp(expr) - fun > transform(expr: KSubArithExpr): KExpr = transformApp(expr) - fun > transform(expr: KUnaryMinusArithExpr): KExpr = transformApp(expr) - fun > transform(expr: KDivArithExpr): KExpr = transformApp(expr) - fun > transform(expr: KPowerArithExpr): KExpr = transformApp(expr) - fun > transform(expr: KLtArithExpr): KExpr = transformApp(expr) - fun > transform(expr: KLeArithExpr): KExpr = transformApp(expr) - fun > transform(expr: KGtArithExpr): KExpr = transformApp(expr) - fun > transform(expr: KGeArithExpr): KExpr = transformApp(expr) + override fun > transform(expr: KAddArithExpr): KExpr = transformApp(expr) + override fun > transform(expr: KMulArithExpr): KExpr = transformApp(expr) + override fun > transform(expr: KSubArithExpr): KExpr = transformApp(expr) + override fun > transform(expr: KUnaryMinusArithExpr): KExpr = transformApp(expr) + override fun > transform(expr: KDivArithExpr): KExpr = transformApp(expr) + override fun > transform(expr: KPowerArithExpr): KExpr = transformApp(expr) + override fun > transform(expr: KLtArithExpr): KExpr = transformApp(expr) + override fun > transform(expr: KLeArithExpr): KExpr = transformApp(expr) + override fun > transform(expr: KGtArithExpr): KExpr = transformApp(expr) + override fun > transform(expr: KGeArithExpr): KExpr = transformApp(expr) // integer transformers - fun transform(expr: KModIntExpr): KExpr = transformApp(expr) - fun transform(expr: KRemIntExpr): KExpr = transformApp(expr) - fun transform(expr: KToRealIntExpr): KExpr = transformApp(expr) + override fun transform(expr: KModIntExpr): KExpr = transformApp(expr) + override fun transform(expr: KRemIntExpr): KExpr = transformApp(expr) + override fun transform(expr: KToRealIntExpr): KExpr = transformApp(expr) + fun transformIntNum(expr: KIntNumExpr): KExpr = transformApp(expr) - fun transform(expr: KInt32NumExpr): KExpr = transformIntNum(expr) - fun transform(expr: KInt64NumExpr): KExpr = transformIntNum(expr) - fun transform(expr: KIntBigNumExpr): KExpr = transformIntNum(expr) + override fun transform(expr: KInt32NumExpr): KExpr = transformIntNum(expr) + override fun transform(expr: KInt64NumExpr): KExpr = transformIntNum(expr) + override fun transform(expr: KIntBigNumExpr): KExpr = transformIntNum(expr) // real transformers - fun transform(expr: KToIntRealExpr): KExpr = transformApp(expr) - fun transform(expr: KIsIntRealExpr): KExpr = transformApp(expr) - fun transform(expr: KRealNumExpr): KExpr = transformApp(expr) + override fun transform(expr: KToIntRealExpr): KExpr = transformApp(expr) + override fun transform(expr: KIsIntRealExpr): KExpr = transformApp(expr) + override fun transform(expr: KRealNumExpr): KExpr = transformApp(expr) // quantifier transformers - fun transform(expr: KExistentialQuantifier): KExpr = with(ctx) { + override fun transform(expr: KExistentialQuantifier): KExpr = with(ctx) { val body = expr.body.accept(this@KTransformer) - if (body == expr.body) return transformExpr(expr) - return transformExpr(mkExistentialQuantifier(body, expr.bounds)) + + return if (body == expr.body) { + transformExpr(expr) + } else { + transformExpr(mkExistentialQuantifier(body, expr.bounds)) + } } - fun transform(expr: KUniversalQuantifier): KExpr = with(ctx) { + override fun transform(expr: KUniversalQuantifier): KExpr = with(ctx) { val body = expr.body.accept(this@KTransformer) - if (body == expr.body) return transformExpr(expr) - return transformExpr(mkUniversalQuantifier(body, expr.bounds)) + + return if (body == expr.body) { + transformExpr(expr) + } else { + transformExpr(mkUniversalQuantifier(body, expr.bounds)) + } } } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/expr/transformer/KTransformerBase.kt b/ksmt-core/src/main/kotlin/org/ksmt/expr/transformer/KTransformerBase.kt new file mode 100644 index 000000000..f941dd5c1 --- /dev/null +++ b/ksmt-core/src/main/kotlin/org/ksmt/expr/transformer/KTransformerBase.kt @@ -0,0 +1,306 @@ +package org.ksmt.expr.transformer + +import org.ksmt.expr.KAddArithExpr +import org.ksmt.expr.KAndExpr +import org.ksmt.expr.KArrayConst +import org.ksmt.expr.KArrayLambda +import org.ksmt.expr.KArraySelect +import org.ksmt.expr.KArrayStore +import org.ksmt.expr.KBitVec16Value +import org.ksmt.expr.KBitVec1Value +import org.ksmt.expr.KBitVec32Value +import org.ksmt.expr.KBitVec64Value +import org.ksmt.expr.KBitVec8Value +import org.ksmt.expr.KBitVecCustomValue +import org.ksmt.expr.KBv2IntExpr +import org.ksmt.expr.KBvAddExpr +import org.ksmt.expr.KBvAddNoOverflowExpr +import org.ksmt.expr.KBvAddNoUnderflowExpr +import org.ksmt.expr.KBvAndExpr +import org.ksmt.expr.KBvArithShiftRightExpr +import org.ksmt.expr.KBvConcatExpr +import org.ksmt.expr.KBvDivNoOverflowExpr +import org.ksmt.expr.KBvExtractExpr +import org.ksmt.expr.KBvLogicalShiftRightExpr +import org.ksmt.expr.KBvMulExpr +import org.ksmt.expr.KBvMulNoOverflowExpr +import org.ksmt.expr.KBvMulNoUnderflowExpr +import org.ksmt.expr.KBvNAndExpr +import org.ksmt.expr.KBvNegNoOverflowExpr +import org.ksmt.expr.KBvNegationExpr +import org.ksmt.expr.KBvNorExpr +import org.ksmt.expr.KBvNotExpr +import org.ksmt.expr.KBvOrExpr +import org.ksmt.expr.KBvReductionAndExpr +import org.ksmt.expr.KBvReductionOrExpr +import org.ksmt.expr.KBvRepeatExpr +import org.ksmt.expr.KBvRotateLeftExpr +import org.ksmt.expr.KBvRotateLeftIndexedExpr +import org.ksmt.expr.KBvRotateRightExpr +import org.ksmt.expr.KBvRotateRightIndexedExpr +import org.ksmt.expr.KBvShiftLeftExpr +import org.ksmt.expr.KBvSignExtensionExpr +import org.ksmt.expr.KBvSignedDivExpr +import org.ksmt.expr.KBvSignedGreaterExpr +import org.ksmt.expr.KBvSignedGreaterOrEqualExpr +import org.ksmt.expr.KBvSignedLessExpr +import org.ksmt.expr.KBvSignedLessOrEqualExpr +import org.ksmt.expr.KBvSignedModExpr +import org.ksmt.expr.KBvSignedRemExpr +import org.ksmt.expr.KBvSubExpr +import org.ksmt.expr.KBvSubNoOverflowExpr +import org.ksmt.expr.KBvSubNoUnderflowExpr +import org.ksmt.expr.KBvToFpExpr +import org.ksmt.expr.KBvUnsignedDivExpr +import org.ksmt.expr.KBvUnsignedGreaterExpr +import org.ksmt.expr.KBvUnsignedGreaterOrEqualExpr +import org.ksmt.expr.KBvUnsignedLessExpr +import org.ksmt.expr.KBvUnsignedLessOrEqualExpr +import org.ksmt.expr.KBvUnsignedRemExpr +import org.ksmt.expr.KBvXNorExpr +import org.ksmt.expr.KBvXorExpr +import org.ksmt.expr.KBvZeroExtensionExpr +import org.ksmt.expr.KConst +import org.ksmt.expr.KDistinctExpr +import org.ksmt.expr.KDivArithExpr +import org.ksmt.expr.KEqExpr +import org.ksmt.expr.KExistentialQuantifier +import org.ksmt.expr.KExpr +import org.ksmt.expr.KFalse +import org.ksmt.expr.KFp128Value +import org.ksmt.expr.KFp16Value +import org.ksmt.expr.KFp32Value +import org.ksmt.expr.KFp64Value +import org.ksmt.expr.KFpAbsExpr +import org.ksmt.expr.KFpAddExpr +import org.ksmt.expr.KFpCustomSizeValue +import org.ksmt.expr.KFpDivExpr +import org.ksmt.expr.KFpEqualExpr +import org.ksmt.expr.KFpFromBvExpr +import org.ksmt.expr.KFpFusedMulAddExpr +import org.ksmt.expr.KFpGreaterExpr +import org.ksmt.expr.KFpGreaterOrEqualExpr +import org.ksmt.expr.KFpIsInfiniteExpr +import org.ksmt.expr.KFpIsNaNExpr +import org.ksmt.expr.KFpIsNegativeExpr +import org.ksmt.expr.KFpIsNormalExpr +import org.ksmt.expr.KFpIsPositiveExpr +import org.ksmt.expr.KFpIsSubnormalExpr +import org.ksmt.expr.KFpIsZeroExpr +import org.ksmt.expr.KFpLessExpr +import org.ksmt.expr.KFpLessOrEqualExpr +import org.ksmt.expr.KFpMaxExpr +import org.ksmt.expr.KFpMinExpr +import org.ksmt.expr.KFpMulExpr +import org.ksmt.expr.KFpNegationExpr +import org.ksmt.expr.KFpRemExpr +import org.ksmt.expr.KFpRoundToIntegralExpr +import org.ksmt.expr.KFpRoundingModeExpr +import org.ksmt.expr.KFpSqrtExpr +import org.ksmt.expr.KFpSubExpr +import org.ksmt.expr.KFpToBvExpr +import org.ksmt.expr.KFpToFpExpr +import org.ksmt.expr.KFpToIEEEBvExpr +import org.ksmt.expr.KFpToRealExpr +import org.ksmt.expr.KFunctionApp +import org.ksmt.expr.KFunctionAsArray +import org.ksmt.expr.KGeArithExpr +import org.ksmt.expr.KGtArithExpr +import org.ksmt.expr.KImpliesExpr +import org.ksmt.expr.KInt32NumExpr +import org.ksmt.expr.KInt64NumExpr +import org.ksmt.expr.KIntBigNumExpr +import org.ksmt.expr.KIsIntRealExpr +import org.ksmt.expr.KIteExpr +import org.ksmt.expr.KLeArithExpr +import org.ksmt.expr.KLtArithExpr +import org.ksmt.expr.KModIntExpr +import org.ksmt.expr.KMulArithExpr +import org.ksmt.expr.KNotExpr +import org.ksmt.expr.KOrExpr +import org.ksmt.expr.KPowerArithExpr +import org.ksmt.expr.KRealNumExpr +import org.ksmt.expr.KRealToFpExpr +import org.ksmt.expr.KRemIntExpr +import org.ksmt.expr.KSubArithExpr +import org.ksmt.expr.KToIntRealExpr +import org.ksmt.expr.KToRealIntExpr +import org.ksmt.expr.KTrue +import org.ksmt.expr.KUnaryMinusArithExpr +import org.ksmt.expr.KUniversalQuantifier +import org.ksmt.expr.KXorExpr +import org.ksmt.sort.KArithSort +import org.ksmt.sort.KArraySort +import org.ksmt.sort.KBoolSort +import org.ksmt.sort.KBv16Sort +import org.ksmt.sort.KBv1Sort +import org.ksmt.sort.KBv32Sort +import org.ksmt.sort.KBv64Sort +import org.ksmt.sort.KBv8Sort +import org.ksmt.sort.KBvSort +import org.ksmt.sort.KFp128Sort +import org.ksmt.sort.KFp16Sort +import org.ksmt.sort.KFp32Sort +import org.ksmt.sort.KFp64Sort +import org.ksmt.sort.KFpRoundingModeSort +import org.ksmt.sort.KFpSort +import org.ksmt.sort.KIntSort +import org.ksmt.sort.KRealSort +import org.ksmt.sort.KSort + + +interface KTransformerBase { + fun transform(expr: KExpr<*>): Any = error("transformer is not implemented for expr $expr") + + // function transformers + fun transform(expr: KFunctionApp): KExpr + fun transform(expr: KConst): KExpr + + // bool transformers + fun transform(expr: KAndExpr): KExpr + fun transform(expr: KOrExpr): KExpr + fun transform(expr: KNotExpr): KExpr + fun transform(expr: KImpliesExpr): KExpr + fun transform(expr: KXorExpr): KExpr + fun transform(expr: KTrue): KExpr + fun transform(expr: KFalse): KExpr + fun transform(expr: KEqExpr): KExpr + fun transform(expr: KDistinctExpr): KExpr + fun transform(expr: KIteExpr): KExpr + + // bit-vec transformers + fun transform(expr: KBitVec1Value): KExpr + fun transform(expr: KBitVec8Value): KExpr + fun transform(expr: KBitVec16Value): KExpr + fun transform(expr: KBitVec32Value): KExpr + fun transform(expr: KBitVec64Value): KExpr + fun transform(expr: KBitVecCustomValue): KExpr + + // bit-vec expressions transformers + fun transform(expr: KBvNotExpr): KExpr + fun transform(expr: KBvReductionAndExpr): KExpr + fun transform(expr: KBvReductionOrExpr): KExpr + fun transform(expr: KBvAndExpr): KExpr + fun transform(expr: KBvOrExpr): KExpr + fun transform(expr: KBvXorExpr): KExpr + fun transform(expr: KBvNAndExpr): KExpr + fun transform(expr: KBvNorExpr): KExpr + fun transform(expr: KBvXNorExpr): KExpr + fun transform(expr: KBvNegationExpr): KExpr + fun transform(expr: KBvAddExpr): KExpr + fun transform(expr: KBvSubExpr): KExpr + fun transform(expr: KBvMulExpr): KExpr + fun transform(expr: KBvUnsignedDivExpr): KExpr + fun transform(expr: KBvSignedDivExpr): KExpr + fun transform(expr: KBvUnsignedRemExpr): KExpr + fun transform(expr: KBvSignedRemExpr): KExpr + fun transform(expr: KBvSignedModExpr): KExpr + fun transform(expr: KBvUnsignedLessExpr): KExpr + fun transform(expr: KBvSignedLessExpr): KExpr + fun transform(expr: KBvUnsignedLessOrEqualExpr): KExpr + fun transform(expr: KBvSignedLessOrEqualExpr): KExpr + fun transform(expr: KBvUnsignedGreaterOrEqualExpr): KExpr + fun transform(expr: KBvSignedGreaterOrEqualExpr): KExpr + fun transform(expr: KBvUnsignedGreaterExpr): KExpr + fun transform(expr: KBvSignedGreaterExpr): KExpr + fun transform(expr: KBvConcatExpr): KExpr + fun transform(expr: KBvExtractExpr): KExpr + fun transform(expr: KBvSignExtensionExpr): KExpr + fun transform(expr: KBvZeroExtensionExpr): KExpr + fun transform(expr: KBvRepeatExpr): KExpr + fun transform(expr: KBvShiftLeftExpr): KExpr + fun transform(expr: KBvLogicalShiftRightExpr): KExpr + fun transform(expr: KBvArithShiftRightExpr): KExpr + fun transform(expr: KBvRotateLeftExpr): KExpr + fun transform(expr: KBvRotateLeftIndexedExpr): KExpr + fun transform(expr: KBvRotateRightExpr): KExpr + fun transform(expr: KBvRotateRightIndexedExpr): KExpr + fun transform(expr: KBv2IntExpr): KExpr + fun transform(expr: KBvAddNoOverflowExpr): KExpr + fun transform(expr: KBvAddNoUnderflowExpr): KExpr + fun transform(expr: KBvSubNoOverflowExpr): KExpr + fun transform(expr: KBvSubNoUnderflowExpr): KExpr + fun transform(expr: KBvDivNoOverflowExpr): KExpr + fun transform(expr: KBvNegNoOverflowExpr): KExpr + fun transform(expr: KBvMulNoOverflowExpr): KExpr + fun transform(expr: KBvMulNoUnderflowExpr): KExpr + + // fp value transformers + fun transform(expr: KFp16Value): KExpr + fun transform(expr: KFp32Value): KExpr + fun transform(expr: KFp64Value): KExpr + fun transform(expr: KFp128Value): KExpr + fun transform(expr: KFpCustomSizeValue): KExpr + + // fp rounding mode + fun transform(expr: KFpRoundingModeExpr): KExpr + + // fp operations tranformation + fun transform(expr: KFpAbsExpr): KExpr + fun transform(expr: KFpNegationExpr): KExpr + fun transform(expr: KFpAddExpr): KExpr + fun transform(expr: KFpSubExpr): KExpr + fun transform(expr: KFpMulExpr): KExpr + fun transform(expr: KFpDivExpr): KExpr + fun transform(expr: KFpFusedMulAddExpr): KExpr + fun transform(expr: KFpSqrtExpr): KExpr + fun transform(expr: KFpRemExpr): KExpr + fun transform(expr: KFpRoundToIntegralExpr): KExpr + fun transform(expr: KFpMinExpr): KExpr + fun transform(expr: KFpMaxExpr): KExpr + fun transform(expr: KFpLessOrEqualExpr): KExpr + fun transform(expr: KFpLessExpr): KExpr + fun transform(expr: KFpGreaterOrEqualExpr): KExpr + fun transform(expr: KFpGreaterExpr): KExpr + fun transform(expr: KFpEqualExpr): KExpr + fun transform(expr: KFpIsNormalExpr): KExpr + fun transform(expr: KFpIsSubnormalExpr): KExpr + fun transform(expr: KFpIsZeroExpr): KExpr + fun transform(expr: KFpIsInfiniteExpr): KExpr + fun transform(expr: KFpIsNaNExpr): KExpr + fun transform(expr: KFpIsNegativeExpr): KExpr + fun transform(expr: KFpIsPositiveExpr): KExpr + fun transform(expr: KFpToBvExpr): KExpr + fun transform(expr: KFpToRealExpr): KExpr + fun transform(expr: KFpToIEEEBvExpr): KExpr + fun transform(expr: KFpFromBvExpr): KExpr + fun transform(expr: KFpToFpExpr): KExpr + fun transform(expr: KRealToFpExpr): KExpr + fun transform(expr: KBvToFpExpr): KExpr + + // array transformers + fun transform(expr: KArrayStore): KExpr> + fun transform(expr: KArraySelect): KExpr + fun transform(expr: KArrayConst): KExpr> + fun transform(expr: KFunctionAsArray): KExpr> + fun transform(expr: KArrayLambda): KExpr> + + // arith transformers + fun > transform(expr: KAddArithExpr): KExpr + fun > transform(expr: KMulArithExpr): KExpr + fun > transform(expr: KSubArithExpr): KExpr + fun > transform(expr: KUnaryMinusArithExpr): KExpr + fun > transform(expr: KDivArithExpr): KExpr + fun > transform(expr: KPowerArithExpr): KExpr + fun > transform(expr: KLtArithExpr): KExpr + fun > transform(expr: KLeArithExpr): KExpr + fun > transform(expr: KGtArithExpr): KExpr + fun > transform(expr: KGeArithExpr): KExpr + + // integer transformers + fun transform(expr: KModIntExpr): KExpr + fun transform(expr: KRemIntExpr): KExpr + fun transform(expr: KToRealIntExpr): KExpr + fun transform(expr: KInt32NumExpr): KExpr + fun transform(expr: KInt64NumExpr): KExpr + fun transform(expr: KIntBigNumExpr): KExpr + + // real transformers + fun transform(expr: KToIntRealExpr): KExpr + fun transform(expr: KIsIntRealExpr): KExpr + fun transform(expr: KRealNumExpr): KExpr + + // quantifier transformers + fun transform(expr: KExistentialQuantifier): KExpr + fun transform(expr: KUniversalQuantifier): KExpr +} diff --git a/ksmt-core/src/main/kotlin/org/ksmt/solver/KModel.kt b/ksmt-core/src/main/kotlin/org/ksmt/solver/KModel.kt index e6d236b7e..4d9d49775 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/solver/KModel.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/solver/KModel.kt @@ -6,8 +6,11 @@ import org.ksmt.sort.KSort interface KModel { val declarations: Set> - fun eval(expr: KExpr, complete: Boolean = false): KExpr + + fun eval(expr: KExpr, isComplete: Boolean = false): KExpr + fun interpretation(decl: KDecl): KFuncInterp? + fun detach(): KModel data class KFuncInterp( diff --git a/ksmt-core/src/main/kotlin/org/ksmt/solver/KSolver.kt b/ksmt-core/src/main/kotlin/org/ksmt/solver/KSolver.kt index ef9773668..39d3ae37c 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/solver/KSolver.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/solver/KSolver.kt @@ -6,12 +6,16 @@ import kotlin.time.Duration interface KSolver : AutoCloseable { - /** Assert an expression into solver. + /** + * Assert an expression into solver. + * * @see check * */ fun assert(expr: KExpr) - /** Assert an expression into solver. + /** + * Assert an expression into solver. + * * @return [KBoolSort] constant which is used to track a given assertion * in unsat cores. * @see checkWithAssumptions @@ -19,18 +23,24 @@ interface KSolver : AutoCloseable { * */ fun assertAndTrack(expr: KExpr): KExpr - /** Create a backtracking point for assertion stack. - * @see pop + /** + * Create a backtracking point for assertion stack. + * + * @see pop * */ fun push() - /** Revert solver assertions state to previously created backtracking point. - * @param n number of pushed scopes to revert. - * @see push + /** + * Revert solver assertions state to previously created backtracking point. + * + * @param n number of pushed scopes to revert. + * @see push * */ fun pop(n: UInt = 1u) - /** Performs satisfiability check of currently asserted expressions. + /** + * Performs satisfiability check of currently asserted expressions. + * * @param timeout solver check timeout. When time limit is reached [KSolverStatus.UNKNOWN] is returned. * @return satisfiability check result. * * [KSolverStatus.SAT] assertions are satisfiable. Satisfying assignment can be retrieved via [model]. @@ -40,7 +50,8 @@ interface KSolver : AutoCloseable { * */ fun check(timeout: Duration = Duration.INFINITE): KSolverStatus - /** Performs satisfiability check of currently asserted expressions and provided assumptions. + /** + * Performs satisfiability check of currently asserted expressions and provided assumptions. * * In case of [KSolverStatus.UNSAT] result assumptions are used for unsat core generation. * @see check @@ -48,18 +59,22 @@ interface KSolver : AutoCloseable { * */ fun checkWithAssumptions(assumptions: List>, timeout: Duration = Duration.INFINITE): KSolverStatus - /** Retrieve the model for the last [check] or [checkWithAssumptions]. + /** + * Retrieve the model for the last [check] or [checkWithAssumptions]. * */ fun model(): KModel - /** Retrieve the unsat core for the last [check] or [checkWithAssumptions]. + /** + * Retrieve the unsat core for the last [check] or [checkWithAssumptions]. + * * Unsat core consists only of: * 1. assumptions provided in [checkWithAssumptions] * 2. track variables corresponding to expressions asserted with [assertAndTrack] * */ fun unsatCore(): List> - /** Retrieve a brief explanation of an [KSolverStatus.UNKNOWN] result. + /** + * Retrieve a brief explanation of an [KSolverStatus.UNKNOWN] result. * The format of resulting string is solver implementation dependent. * */ fun reasonOfUnknown(): String diff --git a/ksmt-core/src/main/kotlin/org/ksmt/solver/model/KModelEvaluator.kt b/ksmt-core/src/main/kotlin/org/ksmt/solver/model/KModelEvaluator.kt index e9fb60caf..ee43a575d 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/solver/model/KModelEvaluator.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/solver/model/KModelEvaluator.kt @@ -34,9 +34,10 @@ import org.ksmt.sort.KUninterpretedSort open class KModelEvaluator( override val ctx: KContext, private val model: KModel, - private val complete: Boolean + private val isComplete: Boolean ) : KTransformer { val evaluatedExpressions: MutableMap, KExpr<*>> = hashMapOf() + private val evaluatedFunctions: MutableMap, KExpr<*>> = hashMapOf() fun KExpr.eval(): KExpr = accept(this@KModelEvaluator) @@ -49,27 +50,35 @@ open class KModelEvaluator( mkApp(expr.decl, expr.args.map { it.eval() }) } + @Suppress("DuplicatedCode") override fun transform(expr: KAndExpr): KExpr = expr.evalExpr { val evaluatedArgs = mutableListOf>() + for (arg in expr.args) { val evaluated = arg.eval() if (evaluated == trueExpr) continue if (evaluated == falseExpr) return@evalExpr falseExpr evaluatedArgs.add(evaluated) } + if (evaluatedArgs.isEmpty()) return@evalExpr trueExpr + mkAnd(evaluatedArgs) } + @Suppress("DuplicatedCode") override fun transform(expr: KOrExpr): KExpr = expr.evalExpr { val evaluatedArgs = mutableListOf>() + for (arg in expr.args) { val evaluated = arg.eval() if (evaluated == falseExpr) continue if (evaluated == trueExpr) return@evalExpr trueExpr evaluatedArgs.add(evaluated) } + if (evaluatedArgs.isEmpty()) return@evalExpr falseExpr + mkOr(evaluatedArgs) } @@ -84,7 +93,9 @@ open class KModelEvaluator( override fun transform(expr: KEqExpr): KExpr = expr.evalExpr { val lhs = expr.lhs.eval() val rhs = expr.rhs.eval() + if (lhs == rhs) return@evalExpr trueExpr + mkEq(lhs, rhs) } @@ -106,10 +117,9 @@ open class KModelEvaluator( @Suppress("UNCHECKED_CAST") - inline fun > E.evalExpr(crossinline eval: KContext.() -> KExpr): KExpr = - evaluatedExpressions.getOrPut(this) { - ctx.eval() - } as KExpr + inline fun > E.evalExpr( + crossinline eval: KContext.() -> KExpr + ): KExpr = evaluatedExpressions.getOrPut(this) { ctx.eval() } as KExpr @Suppress("MemberVisibilityCanBePrivate") fun > KApp.evalFunction(): KExpr = evalExpr { @@ -117,47 +127,58 @@ open class KModelEvaluator( } @Suppress("UNCHECKED_CAST") - fun > KApp.evalFunction(args: List>): KExpr = - evaluatedFunctions.getOrPut(this) { - with(ctx) { - val interpretation = model.interpretation(decl) - if (interpretation == null && !complete) { - return@getOrPut mkApp(decl, args) - } - if (interpretation == null) { - return@getOrPut sort.sampleValue() - } - check(args.size == interpretation.vars.size) { - "${interpretation.vars.size} arguments expected but ${args.size} provided" - } - evalFuncInterp(interpretation, args) - } - } as KExpr + fun > KApp.evalFunction( + args: List> + ): KExpr = evaluatedFunctions.getOrPut(this) { + with(ctx) { + val interpretation = model.interpretation(decl) + if (interpretation == null && !isComplete) { + return@getOrPut mkApp(decl, args) + } - @Suppress("UNCHECKED_CAST") - open fun evalFuncInterp(interpretation: KModel.KFuncInterp, args: List>): KExpr = - with(ctx) { - val varSubstitution = KExprSubstitutor(ctx).apply { - interpretation.vars.zip(args).forEach { (v, a) -> - substitute(mkApp(v, emptyList()) as KExpr, a as KExpr) - } + if (interpretation == null) { + return@getOrPut sort.sampleValue() } - val entries = interpretation.entries.map { entry -> - KModel.KFuncInterpEntry( - entry.args.map { varSubstitution.apply(it) }, - varSubstitution.apply(entry.value) - ) + + check(args.size == interpretation.vars.size) { + "${interpretation.vars.size} arguments expected but ${args.size} provided" } - // in case of partial interpretation we can generate any default expr to preserve expression correctness - val defaultExpr = interpretation.default ?: interpretation.sort.sampleValue() - val default = varSubstitution.apply(defaultExpr) - return entries.foldRight(default) { entry, acc -> - val argBinding = mkAnd(entry.args.zip(args) { ea, a -> mkEq(ea as KExpr, a as KExpr) }) - mkIte(argBinding, entry.value, acc) + + evalFuncInterp(interpretation, args) + } + } as KExpr + + + @Suppress("UNCHECKED_CAST") + open fun evalFuncInterp( + interpretation: KModel.KFuncInterp, + args: List> + ): KExpr = with(ctx) { + val varSubstitution = KExprSubstitutor(ctx).apply { + interpretation.vars.zip(args).forEach { (v, a) -> + val app = mkApp(v, emptyList()) + substitute(app as KExpr, a as KExpr) } } + val entries = interpretation.entries.map { entry -> + KModel.KFuncInterpEntry( + entry.args.map { varSubstitution.apply(it) }, + varSubstitution.apply(entry.value) + ) + } + + // in case of partial interpretation we can generate any default expr to preserve expression correctness + val defaultExpr = interpretation.default ?: interpretation.sort.sampleValue() + val default = varSubstitution.apply(defaultExpr) + + return entries.foldRight(default) { entry, acc -> + val argBinding = mkAnd(entry.args.zip(args) { ea, a -> mkEq(ea as KExpr, a as KExpr) }) + mkIte(argBinding, entry.value, acc) + } + } + @Suppress("UNCHECKED_CAST") open fun T.sampleValue(): KExpr = with(ctx) { accept(object : KSortVisitor> { diff --git a/ksmt-core/src/main/kotlin/org/ksmt/solver/model/KModelImpl.kt b/ksmt-core/src/main/kotlin/org/ksmt/solver/model/KModelImpl.kt index ed8c80170..99706cc5e 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/solver/model/KModelImpl.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/solver/model/KModelImpl.kt @@ -13,12 +13,15 @@ open class KModelImpl( override val declarations: Set> get() = interpretations.keys - override fun eval(expr: KExpr, complete: Boolean): KExpr = - with(KModelEvaluator(ctx, this, complete)) { expr.eval() } + override fun eval( + expr: KExpr, + isComplete: Boolean + ): KExpr = with(KModelEvaluator(ctx, this, isComplete)) { expr.eval() } @Suppress("UNCHECKED_CAST") - override fun interpretation(decl: KDecl): KModel.KFuncInterp? = - interpretations[decl] as? KModel.KFuncInterp + override fun interpretation( + decl: KDecl + ): KModel.KFuncInterp? = interpretations[decl] as? KModel.KFuncInterp override fun detach(): KModel = this } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/solver/util/KExprConverterBase.kt b/ksmt-core/src/main/kotlin/org/ksmt/solver/util/KExprConverterBase.kt index ea3d720f4..313eb1373 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/solver/util/KExprConverterBase.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/solver/util/KExprConverterBase.kt @@ -5,13 +5,16 @@ import org.ksmt.sort.KSort abstract class KExprConverterBase { abstract fun findConvertedNative(expr: T): KExpr<*>? + abstract fun saveConvertedNative(native: T, converted: KExpr<*>) + abstract fun convertNativeExpr(expr: T): ExprConversionResult val exprStack = arrayListOf() fun T.convertFromNative(): KExpr { exprStack.add(this) + while (exprStack.isNotEmpty()) { val expr = exprStack.removeLast() @@ -19,13 +22,13 @@ abstract class KExprConverterBase { val converted = convertNativeExpr(expr) - if (!converted.argumentsConversionRequired) { + if (!converted.isArgumentsConversionRequired) { saveConvertedNative(expr, converted.convertedExpr) } } + @Suppress("UNCHECKED_CAST") - return findConvertedNative(this) as? KExpr - ?: error("expr is not properly converted") + return findConvertedNative(this) as? KExpr ?: error("expr is not properly converted") } /** @@ -38,21 +41,29 @@ abstract class KExprConverterBase { expectedSize: Int, converter: (List>) -> KExpr<*> ): ExprConversionResult { - check(args.size == expectedSize) { "arguments size mismatch: expected $expectedSize, actual ${args.size}" } + check(args.size == expectedSize) { + "arguments size mismatch: expected $expectedSize, actual ${args.size}" + } + val convertedArgs = mutableListOf>() var exprAdded = false var argsReady = true + for (arg in args) { val converted = findConvertedNative(arg) + if (converted != null) { convertedArgs.add(converted) continue } + argsReady = false + if (!exprAdded) { exprStack.add(expr) exprAdded = true } + exprStack.add(arg) } @@ -85,7 +96,11 @@ abstract class KExprConverterBase { args: Array, op: (KExpr, KExpr, KExpr) -> KExpr ) = ensureArgsConvertedAndConvert(this, args, expectedSize = 3) { convertedArgs -> - op(convertedArgs[0] as KExpr, convertedArgs[1] as KExpr, convertedArgs[2] as KExpr) + op( + convertedArgs[0] as KExpr, + convertedArgs[1] as KExpr, + convertedArgs[2] as KExpr + ) } @Suppress("UNCHECKED_CAST", "MagicNumber") @@ -119,7 +134,7 @@ abstract class KExprConverterBase { @JvmInline value class ExprConversionResult(private val expr: KExpr<*>?) { - val argumentsConversionRequired: Boolean + val isArgumentsConversionRequired: Boolean get() = expr == null val convertedExpr: KExpr<*> diff --git a/ksmt-core/src/main/kotlin/org/ksmt/solver/util/KExprInternalizerBase.kt b/ksmt-core/src/main/kotlin/org/ksmt/solver/util/KExprInternalizerBase.kt index f2885e791..750b43345 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/solver/util/KExprInternalizerBase.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/solver/util/KExprInternalizerBase.kt @@ -1,25 +1,26 @@ package org.ksmt.solver.util import org.ksmt.expr.KExpr -import org.ksmt.expr.KFpRoundingMode -import org.ksmt.expr.transformer.KTransformer +import org.ksmt.expr.transformer.KTransformerBase import org.ksmt.solver.util.KExprInternalizerBase.ExprInternalizationResult.Companion.argumentsInternalizationRequired import org.ksmt.solver.util.KExprInternalizerBase.ExprInternalizationResult.Companion.notInitializedInternalizationResult import org.ksmt.sort.KSort -abstract class KExprInternalizerBase : KTransformer { +abstract class KExprInternalizerBase : KTransformerBase { val exprStack = arrayListOf>() /** - * Keeps result of last [KTransformer.transform] invocation. + * Keeps result of last [KTransformerBase.transform] invocation. * */ var lastExprInternalizationResult: ExprInternalizationResult = notInitializedInternalizationResult abstract fun findInternalizedExpr(expr: KExpr<*>): T? + abstract fun saveInternalizedExpr(expr: KExpr<*>, internalized: T) fun KExpr.internalizeExpr(): T { exprStack.add(this) + while (exprStack.isNotEmpty()) { lastExprInternalizationResult = notInitializedInternalizationResult val expr = exprStack.removeLast() @@ -40,7 +41,7 @@ abstract class KExprInternalizerBase : KTransformer { "Internalization result wasn't initialized during expr internalization" } - if (!lastExprInternalizationResult.argumentsInternalizationRequired) { + if (!lastExprInternalizationResult.isArgumentsInternalizationRequired) { saveInternalizedExpr(expr, lastExprInternalizationResult.internalizedExpr()) } } @@ -60,12 +61,13 @@ abstract class KExprInternalizerBase : KTransformer { operation: (A0) -> T ): S = also { val internalizedArg = findInternalizedExpr(arg) - if (internalizedArg == null) { + + lastExprInternalizationResult = if (internalizedArg == null) { exprStack.add(this) exprStack.add(arg) - lastExprInternalizationResult = argumentsInternalizationRequired + argumentsInternalizationRequired } else { - lastExprInternalizationResult = ExprInternalizationResult(operation(internalizedArg as A0)) + ExprInternalizationResult(operation(internalizedArg as A0)) } } @@ -76,13 +78,14 @@ abstract class KExprInternalizerBase : KTransformer { ): S = also { val internalizedArg0 = findInternalizedExpr(arg0) val internalizedArg1 = findInternalizedExpr(arg1) - if (internalizedArg0 == null || internalizedArg1 == null) { + + lastExprInternalizationResult = if (internalizedArg0 == null || internalizedArg1 == null) { exprStack.add(this) internalizedArg0 ?: exprStack.add(arg0) internalizedArg1 ?: exprStack.add(arg1) - lastExprInternalizationResult = argumentsInternalizationRequired + argumentsInternalizationRequired } else { - lastExprInternalizationResult = ExprInternalizationResult( + ExprInternalizationResult( operation(internalizedArg0 as A0, internalizedArg1 as A1) ) } @@ -97,14 +100,17 @@ abstract class KExprInternalizerBase : KTransformer { val internalizedArg0 = findInternalizedExpr(arg0) val internalizedArg1 = findInternalizedExpr(arg1) val internalizedArg2 = findInternalizedExpr(arg2) - if (internalizedArg0 == null || internalizedArg1 == null || internalizedArg2 == null) { + + val someArgumentIsNull = internalizedArg0 == null || internalizedArg1 == null || internalizedArg2 == null + + lastExprInternalizationResult = if (someArgumentIsNull) { exprStack.add(this) internalizedArg0 ?: exprStack.add(arg0) internalizedArg1 ?: exprStack.add(arg1) internalizedArg2 ?: exprStack.add(arg2) - lastExprInternalizationResult = argumentsInternalizationRequired + argumentsInternalizationRequired } else { - lastExprInternalizationResult = ExprInternalizationResult( + ExprInternalizationResult( operation(internalizedArg0 as A0, internalizedArg1 as A1, internalizedArg2 as A2) ) } @@ -153,19 +159,25 @@ abstract class KExprInternalizerBase : KTransformer { val internalizedArgs = mutableListOf() var exprAdded = false var argsReady = true + for (arg in args) { val internalized = findInternalizedExpr(arg) + if (internalized != null) { internalizedArgs.add(internalized as A) continue } + argsReady = false + if (!exprAdded) { exprStack.add(this) exprAdded = true } + exprStack.add(arg) } + lastExprInternalizationResult = if (argsReady) { ExprInternalizationResult(operation(internalizedArgs.toTypedArray())) } else { @@ -175,7 +187,7 @@ abstract class KExprInternalizerBase : KTransformer { @JvmInline value class ExprInternalizationResult(private val value: Any) { - val argumentsInternalizationRequired: Boolean + val isArgumentsInternalizationRequired: Boolean get() = value === argumentsInternalizationRequiredMarker val notInitialized: Boolean diff --git a/ksmt-core/src/main/kotlin/org/ksmt/sort/KSort.kt b/ksmt-core/src/main/kotlin/org/ksmt/sort/KSort.kt index 90d878c12..c1320d30c 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/sort/KSort.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/sort/KSort.kt @@ -9,6 +9,7 @@ abstract class KSort(ctx: KContext) : KAst(ctx) { class KBoolSort internal constructor(ctx: KContext) : KSort(ctx) { override fun accept(visitor: KSortVisitor): T = visitor.visit(this) + override fun print(builder: StringBuilder) { builder.append("Bool") } @@ -19,6 +20,7 @@ abstract class KArithSort>(ctx: KContext) : KSort(ctx) class KIntSort internal constructor(ctx: KContext) : KArithSort(ctx) { override fun accept(visitor: KSortVisitor): T = visitor.visit(this) + override fun print(builder: StringBuilder) { builder.append("Int") } @@ -26,6 +28,7 @@ class KIntSort internal constructor(ctx: KContext) : KArithSort(ctx) { class KRealSort internal constructor(ctx: KContext) : KArithSort(ctx) { override fun accept(visitor: KSortVisitor): T = visitor.visit(this) + override fun print(builder: StringBuilder) { builder.append("Real") } @@ -35,6 +38,7 @@ class KArraySort internal constructor( ctx: KContext, val domain: D, val range: R ) : KSort(ctx) { override fun accept(visitor: KSortVisitor): T = visitor.visit(this) + override fun print(builder: StringBuilder): Unit = with(builder) { append("(Array ") domain.print(this) @@ -100,7 +104,9 @@ sealed class KFpSort(ctx: KContext, val exponentBits: UInt, val significandBits: override fun print(builder: StringBuilder) { builder.append("FP (eBits: $exponentBits) (sBits: $significandBits)") } + override fun accept(visitor: KSortVisitor): T = visitor.visit(this) + abstract fun exponentShiftSize(): Int } @@ -144,8 +150,11 @@ class KFp128Sort(ctx: KContext) : KFpSort(ctx, exponentBits, significandBits) { } } -class KFpCustomSizeSort(ctx: KContext, exponentBits: UInt, significandBits: UInt) : - KFpSort(ctx, exponentBits, significandBits) { +class KFpCustomSizeSort( + ctx: KContext, + exponentBits: UInt, + significandBits: UInt +) : KFpSort(ctx, exponentBits, significandBits) { override fun exponentShiftSize(): Int = (1 shl (exponentBits.toInt() - 1)) - 1 } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/utils/NativeLibraryLoader.kt b/ksmt-core/src/main/kotlin/org/ksmt/utils/NativeLibraryLoader.kt index e16ea6894..4ae32aeed 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/utils/NativeLibraryLoader.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/utils/NativeLibraryLoader.kt @@ -12,6 +12,7 @@ object NativeLibraryLoader { fun load(libraries: (OS) -> List) { val arch = System.getProperty("os.arch") + require(arch in supportedArchs) { "Not supported arch: $arch" } val osName = System.getProperty("os.name").lowercase() @@ -23,11 +24,13 @@ object NativeLibraryLoader { } val librariesToLoad = libraries(os) + for (libName in librariesToLoad) { val osLibName = libName + libraryExt val resourceName = "lib/x64/$osLibName" val libUri = NativeLibraryLoader::class.java.classLoader - .getResource(resourceName)?.toURI() + .getResource(resourceName) + ?.toURI() ?: error("Can't find native library $osLibName") if (libUri.scheme == "file") { @@ -36,10 +39,13 @@ object NativeLibraryLoader { } val libFile = Files.createTempFile(libName, libraryExt) + NativeLibraryLoader::class.java.classLoader - .getResourceAsStream(resourceName)?.use { libResourceStream -> + .getResourceAsStream(resourceName) + ?.use { libResourceStream -> libFile.outputStream().use { libResourceStream.copyTo(it) } } + System.load(libFile.toAbsolutePath().toString()) } } diff --git a/ksmt-core/src/main/kotlin/org/ksmt/utils/Utils.kt b/ksmt-core/src/main/kotlin/org/ksmt/utils/Utils.kt index 67b470f83..1d1df3df3 100644 --- a/ksmt-core/src/main/kotlin/org/ksmt/utils/Utils.kt +++ b/ksmt-core/src/main/kotlin/org/ksmt/utils/Utils.kt @@ -44,6 +44,7 @@ fun Float.getHalfPrecisionExponent(isBiased: Boolean): Int { (signBit shl 4) or otherBits } } + return if (isBiased) unbiasedFp16Exponent + KFp16Sort.exponentShiftSize else unbiasedFp16Exponent } diff --git a/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/SmtLibParser.kt b/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/SmtLibParser.kt index 67bc563b8..7f2fb2099 100644 --- a/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/SmtLibParser.kt +++ b/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/SmtLibParser.kt @@ -12,5 +12,5 @@ interface SmtLibParser { * */ fun parse(ctx: KContext, path: Path): List> - class ParseError(cause: Throwable): Exception(cause) + class ParseError(cause: Throwable) : Exception(cause) } diff --git a/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/TestDataProvider.kt b/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/TestDataProvider.kt index 6b91f4419..aaa22891a 100644 --- a/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/TestDataProvider.kt +++ b/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/TestDataProvider.kt @@ -6,7 +6,8 @@ import kotlin.io.path.listDirectoryEntries object TestDataProvider { fun testDataLocation(): Path = this::class.java.classLoader - .getResource("testData")?.toURI() + .getResource("testData") + ?.toURI() ?.let { Paths.get(it) } ?: error("No test data") diff --git a/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/Util.kt b/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/Util.kt index 57fc24aa9..66b4ac102 100644 --- a/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/Util.kt +++ b/ksmt-core/src/testFixtures/kotlin/org/ksmt/solver/fixtures/Util.kt @@ -8,8 +8,10 @@ inline fun skipUnsupportedSolverFeatures(body: () -> Unit) = try { } catch (ex: NotImplementedError) { val reducedStackTrace = ex.stackTrace.take(5).joinToString("\n") { it.toString() } val report = "${ex.message}\n$reducedStackTrace" + System.err.println(report) // skip test with not implemented feature + Assumptions.assumeTrue(false, ex.message) } catch (ex: KSolverUnsupportedFeatureException) { Assumptions.assumeTrue(false, ex.message) @@ -19,7 +21,9 @@ inline fun parseAndSkipTestIfError(parse: () -> T) = try { parse() } catch (ex: SmtLibParser.ParseError) { val testIgnoreReason = "parse failed -- ${ex.message}" + System.err.println(testIgnoreReason) + Assumptions.assumeTrue(false, testIgnoreReason) /** * assumeTrue throws an exception, diff --git a/ksmt-z3/build.gradle.kts b/ksmt-z3/build.gradle.kts index 86229bd30..b7cfff541 100644 --- a/ksmt-z3/build.gradle.kts +++ b/ksmt-z3/build.gradle.kts @@ -12,7 +12,7 @@ repositories { val z3native by configurations.creating -val z3Version = "4.10.2" +val z3Version = "4.11.2" val z3JavaJar by lazy { z3Release("x64-win", "*.jar") } @@ -112,7 +112,7 @@ tasks.withType { } val implementation = project.configurations["implementation"].dependencies.toSet() val runtimeOnly = project.configurations["runtimeOnly"].dependencies.toSet() - val dependencies = (implementation + runtimeOnly) + val dependencies = (implementation + runtimeOnly) project.configurations.shadow.get().dependencies.addAll(dependencies) } diff --git a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3DeclInternalizer.kt b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3DeclInternalizer.kt index 7b2bf79a3..680395413 100644 --- a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3DeclInternalizer.kt +++ b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3DeclInternalizer.kt @@ -102,12 +102,17 @@ open class KZ3DeclInternalizer( private val z3InternCtx: KZ3InternalizationContext, private val sortInternalizer: KZ3SortInternalizer ) : KDeclVisitor> { - override fun visit(decl: KFuncDecl): FuncDecl<*> = z3InternCtx.internalizeDecl(decl) { + override fun visit( + decl: KFuncDecl + ): FuncDecl<*> = z3InternCtx.internalizeDecl(decl) { val argSorts = decl.argSorts.map { it.accept(sortInternalizer) }.toTypedArray() + z3Ctx.mkFuncDecl(decl.name, argSorts, decl.sort.accept(sortInternalizer)) } - override fun visit(decl: KConstDecl): FuncDecl<*> = z3InternCtx.internalizeDecl(decl) { + override fun visit( + decl: KConstDecl + ): FuncDecl<*> = z3InternCtx.internalizeDecl(decl) { z3Ctx.mkConstDecl(decl.name, decl.sort.accept(sortInternalizer)) } @@ -142,7 +147,7 @@ open class KZ3DeclInternalizer( override fun visit(decl: KIteDecl): FuncDecl<*> = z3InternCtx.internalizeDecl(decl) { val expr = decl.arg0Sort.sample() - z3Ctx.mkITE(z3Ctx.mkTrue(), expr, expr).funcDecl + z3Ctx.mkITE(z3Ctx.mkTrue(), expr, expr).funcDecl } @Suppress("UNCHECKED_CAST") diff --git a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3ExprConverter.kt b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3ExprConverter.kt index 8696eabf2..2443b6fc3 100644 --- a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3ExprConverter.kt +++ b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3ExprConverter.kt @@ -48,7 +48,6 @@ open class KZ3ExprConverter( private val ctx: KContext, private val z3InternCtx: KZ3InternalizationContext ) : KExprConverterBase>() { - override fun findConvertedNative(expr: Expr<*>): KExpr<*>? { return z3InternCtx.findConvertedExpr(expr) } @@ -72,6 +71,7 @@ open class KZ3ExprConverter( open fun convertDecl(decl: FuncDecl<*>): KDecl<*> = with(ctx) { val sort = convertSort(decl.range) val args = decl.domain.map { convertSort(it) } + return mkFuncDecl("${decl.name}", sort, args) } @@ -88,7 +88,6 @@ open class KZ3ExprConverter( val fpSort = sort as FPSort mkFpSort(fpSort.eBits.toUInt(), fpSort.sBits.toUInt()) } - Z3_sort_kind.Z3_UNINTERPRETED_SORT -> mkUninterpretedSort(sort.name.toString()) Z3_sort_kind.Z3_ROUNDING_MODE_SORT -> mkFpRoundingModeSort() Z3_sort_kind.Z3_DATATYPE_SORT, @@ -205,19 +204,23 @@ open class KZ3ExprConverter( Z3_decl_kind.Z3_OP_CONCAT -> expr.convertReduced(::mkBvConcatExpr) Z3_decl_kind.Z3_OP_SIGN_EXT -> expr.convert { arg: KExpr -> val size = expr.funcDecl.parameters[0].int + mkBvSignExtensionExpr(size, arg) } Z3_decl_kind.Z3_OP_ZERO_EXT -> expr.convert { arg: KExpr -> val size = expr.funcDecl.parameters[0].int + mkBvZeroExtensionExpr(size, arg) } Z3_decl_kind.Z3_OP_EXTRACT -> expr.convert { arg: KExpr -> val high = expr.funcDecl.parameters[0].int val low = expr.funcDecl.parameters[1].int + mkBvExtractExpr(high, low, arg) } Z3_decl_kind.Z3_OP_REPEAT -> expr.convert { arg: KExpr -> val repeatCount = expr.funcDecl.parameters[0].int + mkBvRepeatExpr(repeatCount, arg) } Z3_decl_kind.Z3_OP_BREDOR -> expr.convert(::mkBvReductionOrExpr) @@ -228,10 +231,12 @@ open class KZ3ExprConverter( Z3_decl_kind.Z3_OP_BASHR -> expr.convert(::mkBvArithShiftRightExpr) Z3_decl_kind.Z3_OP_ROTATE_LEFT -> expr.convert { arg: KExpr -> val rotation = expr.funcDecl.parameters[0].int + mkBvRotateLeftExpr(rotation, arg) } Z3_decl_kind.Z3_OP_ROTATE_RIGHT -> expr.convert { arg: KExpr -> val rotation = expr.funcDecl.parameters[0].int + mkBvRotateRightExpr(rotation, arg) } Z3_decl_kind.Z3_OP_EXT_ROTATE_LEFT -> expr.convert(::mkBvRotateLeftExpr) @@ -261,8 +266,7 @@ open class KZ3ExprConverter( val z3Decl = expr.funcDecl.parameters[0].funcDecl @Suppress("UNCHECKED_CAST") - val decl = convertDecl(z3Decl) as? KFuncDecl - ?: error("unexpected as-array decl $z3Decl") + val decl = convertDecl(z3Decl) as? KFuncDecl ?: error("unexpected as-array decl $z3Decl") mkFunctionAsArray(decl) } @@ -348,6 +352,7 @@ open class KZ3ExprConverter( val fpSort = convertSort(expr.sort) as KFpSort val args = expr.args val sorts = args.map { it.sort } + return when { args.size == 1 && sorts[0] is BitVecSort -> expr.convert { bv: KExpr -> val exponentBits = fpSort.exponentBits.toInt() @@ -376,16 +381,20 @@ open class KZ3ExprConverter( expr.convert { sign: KExpr, exp: KExpr, significand: KExpr -> mkFpFromBvExpr(sign, exp, significand) } - args.size == 3 && sorts[0] is FPRMSort && sorts[1] is ArithSort && sorts[2] is ArithSort -> - expr.convert, KArithSort<*>> { - rm: KExpr, arg1: KExpr>, arg2: KExpr> -> - TODO("${rm.sort} + real (${arg1.sort}) + int (${arg2.sort}) -> float") - } + expr.convert(::convertRealToFpExpr) else -> error("unexpected fpaTofp: $expr") } } + private fun convertRealToFpExpr( + rm: KExpr, + arg1: KExpr>, + arg2: KExpr> + ): KExpr = with(ctx) { + TODO("unsupported fpaTofp: ${rm.sort} + real (${arg1.sort}) + int (${arg2.sort}) -> float") + } + open fun convertNumeral(expr: Expr<*>): ExprConversionResult = when (expr.sort.sortKind) { Z3_sort_kind.Z3_INT_SORT -> convert { convertNumeral(expr as IntNum) } Z3_sort_kind.Z3_REAL_SORT -> convert { convertNumeral(expr as RatNum) } @@ -397,7 +406,8 @@ open class KZ3ExprConverter( @Suppress("MemberVisibilityCanBePrivate") fun convertNumeral(expr: IntNum): KIntNumExpr = with(ctx) { - expr.intOrNull()?.let { mkIntNum(it) } + expr.intOrNull() + ?.let { mkIntNum(it) } ?: expr.longOrNull()?.let { mkIntNum(it) } ?: mkIntNum(expr.bigInteger) } @@ -460,9 +470,11 @@ open class KZ3ExprConverter( val preparedBody = expr.body.substituteVars(z3Bounds.toTypedArray()) val body = findConvertedNative(preparedBody) + if (body == null) { exprStack.add(expr) exprStack.add(preparedBody) + return argumentsConversionRequired } @@ -477,6 +489,7 @@ open class KZ3ExprConverter( expr.isLambda -> TODO("array lambda converter") else -> TODO("unexpected quantifier: $expr") } + ExprConversionResult(convertedExpr) } diff --git a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3ExprInternalizer.kt b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3ExprInternalizer.kt index 61ac4c2f7..60dfc1383 100644 --- a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3ExprInternalizer.kt +++ b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3ExprInternalizer.kt @@ -153,10 +153,12 @@ import org.ksmt.expr.KFpToFpExpr import org.ksmt.expr.KFpToIEEEBvExpr import org.ksmt.expr.KFpToRealExpr import org.ksmt.expr.KFpValue +import org.ksmt.expr.KFunctionAsArray import org.ksmt.expr.KRealToFpExpr import org.ksmt.expr.KXorExpr import org.ksmt.solver.util.KExprInternalizerBase import org.ksmt.sort.KArithSort +import org.ksmt.sort.KArraySort import org.ksmt.sort.KBoolSort import org.ksmt.sort.KBvSort import org.ksmt.sort.KFp128Sort @@ -170,14 +172,14 @@ import org.ksmt.sort.KSort @Suppress("SpreadOperator") open class KZ3ExprInternalizer( - override val ctx: KContext, + val ctx: KContext, private val z3Ctx: Context, private val z3InternCtx: KZ3InternalizationContext, private val sortInternalizer: KZ3SortInternalizer, private val declInternalizer: KZ3DeclInternalizer ) : KExprInternalizerBase>() { - override fun findInternalizedExpr(expr: KExpr<*>): Expr<*>? = z3InternCtx.findInternalizedExpr(expr) + override fun saveInternalizedExpr(expr: KExpr<*>, internalized: Expr<*>) { z3InternCtx.internalizeExpr(expr) { internalized } } @@ -188,9 +190,6 @@ open class KZ3ExprInternalizer( fun T.internalizeSort(): Sort = accept(sortInternalizer) - override fun transformExpr(expr: KExpr): KExpr = - error("Unexpected expr $expr") - override fun transform(expr: KFunctionApp) = with(expr) { transformList(args) { args: Array> -> z3Ctx.mkApp(decl.internalizeDecl(), *args) @@ -231,8 +230,9 @@ open class KZ3ExprInternalizer( ) } - override fun transformBitVecValue(expr: KBitVecValue) = expr.transform { + fun transformBitVecValue(expr: KBitVecValue) = expr.transform { val sizeBits = expr.sort().sizeBits.toInt() + when (expr) { is KBitVec1Value -> z3Ctx.mkBvNumeral(booleanArrayOf(expr.value)) is KBitVec8Value, is KBitVec16Value, is KBitVec32Value -> { @@ -244,6 +244,7 @@ open class KZ3ExprInternalizer( BooleanArray(value.length) { value[it] == '1' } } check(bits.size == sizeBits) { "bv bits size mismatch" } + z3Ctx.mkBvNumeral(bits) } else -> error("Unknown bv expression class ${expr::class} in transformation method: $expr") @@ -348,15 +349,15 @@ open class KZ3ExprInternalizer( } override fun transform(expr: KBvSignExtensionExpr) = with(expr) { - transform(value) { value: BitVecExpr -> z3Ctx.mkSignExt(i, value) } + transform(value) { value: BitVecExpr -> z3Ctx.mkSignExt(extensionSize, value) } } override fun transform(expr: KBvZeroExtensionExpr) = with(expr) { - transform(value) { value: BitVecExpr -> z3Ctx.mkZeroExt(i, value) } + transform(value) { value: BitVecExpr -> z3Ctx.mkZeroExt(extensionSize, value) } } override fun transform(expr: KBvRepeatExpr) = with(expr) { - transform(value) { value: BitVecExpr -> z3Ctx.mkRepeat(i, value) } + transform(value) { value: BitVecExpr -> z3Ctx.mkRepeat(repeatNumber, value) } } override fun transform(expr: KBvShiftLeftExpr) = @@ -372,14 +373,14 @@ open class KZ3ExprInternalizer( with(expr) { transform(arg0, arg1, z3Ctx::mkBVRotateLeft) } override fun transform(expr: KBvRotateLeftIndexedExpr) = with(expr) { - transform(value) { value: BitVecExpr -> z3Ctx.mkBVRotateLeft(i, value) } + transform(value) { value: BitVecExpr -> z3Ctx.mkBVRotateLeft(rotationNumber, value) } } override fun transform(expr: KBvRotateRightExpr) = with(expr) { transform(arg0, arg1, z3Ctx::mkBVRotateRight) } override fun transform(expr: KBvRotateRightIndexedExpr) = with(expr) { - transform(value) { value: BitVecExpr -> z3Ctx.mkBVRotateRight(i, value) } + transform(value) { value: BitVecExpr -> z3Ctx.mkBVRotateRight(rotationNumber, value) } } override fun transform(expr: KBv2IntExpr) = with(expr) { @@ -419,8 +420,9 @@ open class KZ3ExprInternalizer( override fun transform(expr: KBvMulNoUnderflowExpr) = with(expr) { transform(arg0, arg1, z3Ctx::mkBVMulNoUnderflow) } - override fun transformFpValue(expr: KFpValue): KExpr = expr.transform { + fun transformFpValue(expr: KFpValue): KExpr = expr.transform { val sort = with(ctx) { expr.sort.internalizeSort() } as FPSort + with(expr) { when (this) { is KFp16Value -> z3Ctx.mkFP(value, sort) @@ -699,4 +701,8 @@ open class KZ3ExprInternalizer( ) } } + + override fun transform(expr: KFunctionAsArray): KExpr> { + TODO("KFunctionAsArray internalization is not implemented in z3") + } } diff --git a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3InternalizationContext.kt b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3InternalizationContext.kt index e42c25cd8..4be9a6f34 100644 --- a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3InternalizationContext.kt +++ b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3InternalizationContext.kt @@ -6,12 +6,10 @@ import com.microsoft.z3.Sort import org.ksmt.decl.KDecl import org.ksmt.expr.KExpr import org.ksmt.sort.KSort -import java.lang.ref.WeakReference -import java.util.WeakHashMap @Suppress("TooManyFunctions") class KZ3InternalizationContext : AutoCloseable { - private var closed = false + private var isClosed = false private val expressions = HashMap, Expr<*>>() private val z3Expressions = HashMap, KExpr<*>>() private val sorts = HashMap() @@ -20,7 +18,7 @@ class KZ3InternalizationContext : AutoCloseable { private val z3Decls = HashMap, KDecl<*>>() val isActive: Boolean - get() = !closed + get() = !isClosed fun findInternalizedExpr(expr: KExpr<*>): Expr<*>? = expressions[expr] @@ -66,11 +64,12 @@ class KZ3InternalizationContext : AutoCloseable { val converted = converter(key) cache.getOrPut(converted) { key } reverseCache[key] = converted + return converted } override fun close() { - closed = true + isClosed = true sorts.clear() decls.clear() expressions.clear() diff --git a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3Model.kt b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3Model.kt index 1d5e12611..10aad4b0f 100644 --- a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3Model.kt +++ b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3Model.kt @@ -18,16 +18,18 @@ open class KZ3Model( ) : KModel { override val declarations: Set> by lazy { with(converter) { - model.decls.mapTo(mutableSetOf()) { it.convert() } + model.decls.mapTo(hashSetOf()) { it.convert() } } } - private val interpretations = mutableMapOf, KModel.KFuncInterp<*>?>() + private val interpretations = hashMapOf, KModel.KFuncInterp<*>?>() - override fun eval(expr: KExpr, complete: Boolean): KExpr { + override fun eval(expr: KExpr, isComplete: Boolean): KExpr { ensureContextActive() + val z3Expr = with(internalizer) { expr.internalize() } - val z3Result = model.eval(z3Expr, complete) + val z3Result = model.eval(z3Expr, isComplete) + return with(converter) { z3Result.convert() } } @@ -35,8 +37,11 @@ open class KZ3Model( override fun interpretation(decl: KDecl): KModel.KFuncInterp? = interpretations.getOrPut(decl) { ensureContextActive() + if (decl !in declarations) return@getOrPut null + val z3Decl = with(internalizer) { decl.internalizeDecl() } + when (z3Decl) { in model.constDecls -> constInterp(z3Decl) in model.funcDecls -> funcInterp(z3Decl) @@ -46,7 +51,9 @@ open class KZ3Model( private fun constInterp(decl: FuncDecl<*>): KModel.KFuncInterp? { val z3Expr = model.getConstInterp(decl) ?: return null + val expr = with(converter) { z3Expr.convert() } + return with(ctx) { KModel.KFuncInterp(sort = expr.sort, vars = emptyList(), entries = emptyList(), default = expr) } @@ -54,17 +61,21 @@ open class KZ3Model( private fun funcInterp(decl: FuncDecl<*>): KModel.KFuncInterp? = with(converter) { val z3Interp = model.getFuncInterp(decl) ?: return null + val varSorts = decl.domain.map { it.convert() } val vars = varSorts.map { with(ctx) { it.mkFreshConst("x") } } val z3Vars = vars.map { with(internalizer) { it.internalize() } }.toTypedArray() + val entries = z3Interp.entries.map { entry -> val args = entry.args.map { it.substituteVars(z3Vars).convert() } val value = entry.value.substituteVars(z3Vars).convert() KModel.KFuncInterpEntry(args, value) } + val default = z3Interp.getElse().substituteVars(z3Vars).convert() val sort = decl.range.convert() val varDecls = vars.map { with(ctx) { it.decl } } + return KModel.KFuncInterp(sort, varDecls, entries, default) } @@ -72,6 +83,7 @@ open class KZ3Model( val interpretations = declarations.associateWith { interpretation(it) ?: error("missed interpretation for $it") } + return KModelImpl(ctx, interpretations) } diff --git a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3Solver.kt b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3Solver.kt index 0eb0fc068..f8f0d47c5 100644 --- a/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3Solver.kt +++ b/ksmt-z3/src/main/kotlin/org/ksmt/solver/z3/KZ3Solver.kt @@ -125,6 +125,7 @@ open class KZ3Solver(private val ctx: KContext) : KSolver { "Model are only available after SAT checks, current solver status: $lastCheckStatus" } val model = solver.model + KZ3Model(model, ctx, z3InternCtx, exprInternalizer, exprConverter) } @@ -192,6 +193,7 @@ open class KZ3Solver(private val ctx: KContext) : KSolver { cleanupStaleContexts() val cleanupHandler = PhantomReference(solver, cleanupHandlers) contextForCleanup[cleanupHandler] = context + return cleanupHandler } diff --git a/ksmt-z3/src/test/kotlin/org/ksmt/solver/z3/BenchmarksBasedTest.kt b/ksmt-z3/src/test/kotlin/org/ksmt/solver/z3/BenchmarksBasedTest.kt index 11dba8b58..7ecab2cea 100644 --- a/ksmt-z3/src/test/kotlin/org/ksmt/solver/z3/BenchmarksBasedTest.kt +++ b/ksmt-z3/src/test/kotlin/org/ksmt/solver/z3/BenchmarksBasedTest.kt @@ -151,7 +151,7 @@ class BenchmarksBasedTest { with(converter) { assignments.map { (const, value) -> const.convert() to value } } } val assignmentsToCheck = expectedModelAssignments.map { (const, expectedValue) -> - val actualValue = actualModel.eval(const, complete = false) + val actualValue = actualModel.eval(const, isComplete = false) Triple(const, expectedValue, actualValue) } diff --git a/ksmt-z3/src/testFixtures/kotlin/org/ksmt/solver/fixtures/z3/Z3SmtLibParser.kt b/ksmt-z3/src/testFixtures/kotlin/org/ksmt/solver/fixtures/z3/Z3SmtLibParser.kt index 2669e3bd7..b7a517684 100644 --- a/ksmt-z3/src/testFixtures/kotlin/org/ksmt/solver/fixtures/z3/Z3SmtLibParser.kt +++ b/ksmt-z3/src/testFixtures/kotlin/org/ksmt/solver/fixtures/z3/Z3SmtLibParser.kt @@ -33,6 +33,7 @@ class Z3SmtLibParser : SmtLibParser { fun convert(ctx: KContext, assertions: List): List> { val internCtx = KZ3InternalizationContext() val converter = KZ3ExprConverter(ctx, internCtx) + return with(converter) { assertions.map { it.convert() } } } diff --git a/version.properties b/version.properties index a0de21d8e..63eff5024 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ -kotlin=1.6.21 +kotlin=1.7.10 detekt=1.20.0