
main.io.ksmt.solver.z3.KZ3ExprInternalizer.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ksmt-z3-core Show documentation
Show all versions of ksmt-z3-core Show documentation
Kotlin API for various SMT solvers
package io.ksmt.solver.z3
import com.microsoft.z3.Native
import com.microsoft.z3.mkQuantifier
import io.ksmt.KContext
import io.ksmt.decl.KDecl
import io.ksmt.expr.KAddArithExpr
import io.ksmt.expr.KAndBinaryExpr
import io.ksmt.expr.KAndExpr
import io.ksmt.expr.KArray2Lambda
import io.ksmt.expr.KArray2Select
import io.ksmt.expr.KArray2Store
import io.ksmt.expr.KArray3Lambda
import io.ksmt.expr.KArray3Select
import io.ksmt.expr.KArray3Store
import io.ksmt.expr.KArrayConst
import io.ksmt.expr.KArrayLambda
import io.ksmt.expr.KArrayNLambda
import io.ksmt.expr.KArrayNSelect
import io.ksmt.expr.KArrayNStore
import io.ksmt.expr.KArraySelect
import io.ksmt.expr.KArrayStore
import io.ksmt.expr.KBitVec16Value
import io.ksmt.expr.KBitVec1Value
import io.ksmt.expr.KBitVec32Value
import io.ksmt.expr.KBitVec64Value
import io.ksmt.expr.KBitVec8Value
import io.ksmt.expr.KBitVecCustomValue
import io.ksmt.expr.KBitVecNumberValue
import io.ksmt.expr.KBitVecValue
import io.ksmt.expr.KBv2IntExpr
import io.ksmt.expr.KBvAddExpr
import io.ksmt.expr.KBvAddNoOverflowExpr
import io.ksmt.expr.KBvAddNoUnderflowExpr
import io.ksmt.expr.KBvAndExpr
import io.ksmt.expr.KBvArithShiftRightExpr
import io.ksmt.expr.KBvConcatExpr
import io.ksmt.expr.KBvDivNoOverflowExpr
import io.ksmt.expr.KBvExtractExpr
import io.ksmt.expr.KBvLogicalShiftRightExpr
import io.ksmt.expr.KBvMulExpr
import io.ksmt.expr.KBvMulNoOverflowExpr
import io.ksmt.expr.KBvMulNoUnderflowExpr
import io.ksmt.expr.KBvNAndExpr
import io.ksmt.expr.KBvNegNoOverflowExpr
import io.ksmt.expr.KBvNegationExpr
import io.ksmt.expr.KBvNorExpr
import io.ksmt.expr.KBvNotExpr
import io.ksmt.expr.KBvOrExpr
import io.ksmt.expr.KBvReductionAndExpr
import io.ksmt.expr.KBvReductionOrExpr
import io.ksmt.expr.KBvRepeatExpr
import io.ksmt.expr.KBvRotateLeftExpr
import io.ksmt.expr.KBvRotateLeftIndexedExpr
import io.ksmt.expr.KBvRotateRightExpr
import io.ksmt.expr.KBvRotateRightIndexedExpr
import io.ksmt.expr.KBvShiftLeftExpr
import io.ksmt.expr.KBvSignExtensionExpr
import io.ksmt.expr.KBvSignedDivExpr
import io.ksmt.expr.KBvSignedGreaterExpr
import io.ksmt.expr.KBvSignedGreaterOrEqualExpr
import io.ksmt.expr.KBvSignedLessExpr
import io.ksmt.expr.KBvSignedLessOrEqualExpr
import io.ksmt.expr.KBvSignedModExpr
import io.ksmt.expr.KBvSignedRemExpr
import io.ksmt.expr.KBvSubExpr
import io.ksmt.expr.KBvSubNoOverflowExpr
import io.ksmt.expr.KBvSubNoUnderflowExpr
import io.ksmt.expr.KBvToFpExpr
import io.ksmt.expr.KBvUnsignedDivExpr
import io.ksmt.expr.KBvUnsignedGreaterExpr
import io.ksmt.expr.KBvUnsignedGreaterOrEqualExpr
import io.ksmt.expr.KBvUnsignedLessExpr
import io.ksmt.expr.KBvUnsignedLessOrEqualExpr
import io.ksmt.expr.KBvUnsignedRemExpr
import io.ksmt.expr.KBvXNorExpr
import io.ksmt.expr.KBvXorExpr
import io.ksmt.expr.KBvZeroExtensionExpr
import io.ksmt.expr.KConst
import io.ksmt.expr.KDistinctExpr
import io.ksmt.expr.KDivArithExpr
import io.ksmt.expr.KEqExpr
import io.ksmt.expr.KExistentialQuantifier
import io.ksmt.expr.KExpr
import io.ksmt.expr.KFalse
import io.ksmt.expr.KFp128Value
import io.ksmt.expr.KFp16Value
import io.ksmt.expr.KFp32Value
import io.ksmt.expr.KFp64Value
import io.ksmt.expr.KFpAbsExpr
import io.ksmt.expr.KFpAddExpr
import io.ksmt.expr.KFpCustomSizeValue
import io.ksmt.expr.KFpDivExpr
import io.ksmt.expr.KFpEqualExpr
import io.ksmt.expr.KFpFromBvExpr
import io.ksmt.expr.KFpFusedMulAddExpr
import io.ksmt.expr.KFpGreaterExpr
import io.ksmt.expr.KFpGreaterOrEqualExpr
import io.ksmt.expr.KFpIsInfiniteExpr
import io.ksmt.expr.KFpIsNaNExpr
import io.ksmt.expr.KFpIsNegativeExpr
import io.ksmt.expr.KFpIsNormalExpr
import io.ksmt.expr.KFpIsPositiveExpr
import io.ksmt.expr.KFpIsSubnormalExpr
import io.ksmt.expr.KFpIsZeroExpr
import io.ksmt.expr.KFpLessExpr
import io.ksmt.expr.KFpLessOrEqualExpr
import io.ksmt.expr.KFpMaxExpr
import io.ksmt.expr.KFpMinExpr
import io.ksmt.expr.KFpMulExpr
import io.ksmt.expr.KFpNegationExpr
import io.ksmt.expr.KFpRemExpr
import io.ksmt.expr.KFpRoundToIntegralExpr
import io.ksmt.expr.KFpRoundingMode
import io.ksmt.expr.KFpRoundingModeExpr
import io.ksmt.expr.KFpSqrtExpr
import io.ksmt.expr.KFpSubExpr
import io.ksmt.expr.KFpToBvExpr
import io.ksmt.expr.KFpToFpExpr
import io.ksmt.expr.KFpToIEEEBvExpr
import io.ksmt.expr.KFpToRealExpr
import io.ksmt.expr.KFunctionApp
import io.ksmt.expr.KFunctionAsArray
import io.ksmt.expr.KGeArithExpr
import io.ksmt.expr.KGtArithExpr
import io.ksmt.expr.KImpliesExpr
import io.ksmt.expr.KInt32NumExpr
import io.ksmt.expr.KInt64NumExpr
import io.ksmt.expr.KIntBigNumExpr
import io.ksmt.expr.KIsIntRealExpr
import io.ksmt.expr.KIteExpr
import io.ksmt.expr.KLeArithExpr
import io.ksmt.expr.KLtArithExpr
import io.ksmt.expr.KModIntExpr
import io.ksmt.expr.KMulArithExpr
import io.ksmt.expr.KNotExpr
import io.ksmt.expr.KOrBinaryExpr
import io.ksmt.expr.KOrExpr
import io.ksmt.expr.KPowerArithExpr
import io.ksmt.expr.KQuantifier
import io.ksmt.expr.KRealNumExpr
import io.ksmt.expr.KRealToFpExpr
import io.ksmt.expr.KRemIntExpr
import io.ksmt.expr.KSubArithExpr
import io.ksmt.expr.KToIntRealExpr
import io.ksmt.expr.KToRealIntExpr
import io.ksmt.expr.KTrue
import io.ksmt.expr.KUnaryMinusArithExpr
import io.ksmt.expr.KUninterpretedSortValue
import io.ksmt.expr.KUniversalQuantifier
import io.ksmt.expr.KXorExpr
import io.ksmt.solver.util.KExprLongInternalizerBase
import io.ksmt.sort.KArithSort
import io.ksmt.sort.KArray2Sort
import io.ksmt.sort.KArray3Sort
import io.ksmt.sort.KArrayNSort
import io.ksmt.sort.KArraySort
import io.ksmt.sort.KArraySortBase
import io.ksmt.sort.KBoolSort
import io.ksmt.sort.KBvSort
import io.ksmt.sort.KFp128Sort
import io.ksmt.sort.KFp16Sort
import io.ksmt.sort.KFp32Sort
import io.ksmt.sort.KFp64Sort
import io.ksmt.sort.KFpRoundingModeSort
import io.ksmt.sort.KFpSort
import io.ksmt.sort.KRealSort
import io.ksmt.sort.KSort
import io.ksmt.sort.KUninterpretedSort
open class KZ3ExprInternalizer(
val ctx: KContext,
private val z3InternCtx: KZ3Context
) : KExprLongInternalizerBase() {
@JvmField
val nCtx: Long = z3InternCtx.nCtx
private val sortInternalizer = KZ3SortInternalizer(z3InternCtx)
private val declInternalizer = KZ3DeclInternalizer(z3InternCtx, sortInternalizer)
override fun findInternalizedExpr(expr: KExpr<*>): Long =
z3InternCtx.findInternalizedExpr(expr)
override fun saveInternalizedExpr(expr: KExpr<*>, internalized: Long) {
z3InternCtx.saveInternalizedExpr(expr, internalized)
}
fun > T.internalizeDecl(): Long = declInternalizer.internalizeZ3Decl(this)
fun T.internalizeSort(): Long = sortInternalizer.internalizeZ3Sort(this)
override fun transform(expr: KFunctionApp) = with(expr) {
transformArray(args) { args ->
Native.mkApp(nCtx, decl.internalizeDecl(), args.size, args)
}
}
override fun transform(expr: KConst) = with(expr) {
transform { Native.mkApp(nCtx, decl.internalizeDecl(), 0, null) }
}
override fun transform(expr: KAndExpr) = with(expr) {
transformArray(args) { args -> Native.mkAnd(nCtx, args.size, args) }
}
override fun transform(expr: KAndBinaryExpr) = with(expr) {
transform(lhs, rhs) { l, r -> Native.mkAnd(nCtx, 2, longArrayOf(l, r)) }
}
override fun transform(expr: KOrExpr) = with(expr) {
transformArray(args) { args -> Native.mkOr(nCtx, args.size, args) }
}
override fun transform(expr: KOrBinaryExpr) = with(expr) {
transform(lhs, rhs) { l, r -> Native.mkOr(nCtx, 2, longArrayOf(l, r)) }
}
override fun transform(expr: KNotExpr) = with(expr) { transform(arg, Native::mkNot) }
override fun transform(expr: KImpliesExpr) = with(expr) { transform(p, q, Native::mkImplies) }
override fun transform(expr: KXorExpr) = with(expr) { transform(a, b, Native::mkXor) }
override fun transform(expr: KTrue) = expr.transform { Native.mkTrue(nCtx) }
override fun transform(expr: KFalse) = expr.transform { Native.mkFalse(nCtx) }
override fun transform(expr: KEqExpr) = with(expr) { transform(lhs, rhs, Native::mkEq) }
override fun transform(expr: KDistinctExpr) = with(expr) {
transformArray(args) { args -> Native.mkDistinct(nCtx, args.size, args) }
}
override fun transform(expr: KIteExpr) = with(expr) {
transform(condition, trueBranch, falseBranch, Native::mkIte)
}
fun transformBitVecValue(expr: KBitVecValue) = expr.transform {
when (expr) {
is KBitVec1Value -> {
val bits = booleanArrayOf(expr.value)
Native.mkBvNumeral(nCtx, bits.size, bits)
}
is KBitVec8Value -> {
val sort = expr.sort.internalizeSort()
Native.mkInt(nCtx, expr.byteValue.toInt(), sort)
}
is KBitVec16Value -> {
val sort = expr.sort.internalizeSort()
Native.mkInt(nCtx, expr.shortValue.toInt(), sort)
}
is KBitVec32Value -> {
val sort = expr.sort.internalizeSort()
Native.mkInt(nCtx, expr.intValue, sort)
}
is KBitVec64Value -> {
val sort = expr.sort.internalizeSort()
Native.mkInt64(nCtx, expr.longValue, sort)
}
is KBitVecCustomValue -> {
val bits = BooleanArray(expr.sizeBits.toInt()) { expr.value.testBit(it) }
Native.mkBvNumeral(nCtx, bits.size, bits)
}
else -> error("Unknown bv expression class ${expr::class} in transformation method: $expr")
}
}
override fun transform(expr: KBitVec1Value) = transformBitVecValue(expr)
override fun transform(expr: KBitVec8Value) = transformBitVecValue(expr)
override fun transform(expr: KBitVec16Value) = transformBitVecValue(expr)
override fun transform(expr: KBitVec32Value) = transformBitVecValue(expr)
override fun transform(expr: KBitVec64Value) = transformBitVecValue(expr)
override fun transform(expr: KBitVecCustomValue) = transformBitVecValue(expr)
override fun transform(expr: KBvNotExpr) =
with(expr) { transform(value, Native::mkBvnot) }
override fun transform(expr: KBvReductionAndExpr) =
with(expr) { transform(value, Native::mkBvredand) }
override fun transform(expr: KBvReductionOrExpr) =
with(expr) { transform(value, Native::mkBvredor) }
override fun transform(expr: KBvAndExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvand) }
override fun transform(expr: KBvOrExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvor) }
override fun transform(expr: KBvXorExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvxor) }
override fun transform(expr: KBvNAndExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvnand) }
override fun transform(expr: KBvNorExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvnor) }
override fun transform(expr: KBvXNorExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvxnor) }
override fun transform(expr: KBvNegationExpr) =
with(expr) { transform(value, Native::mkBvneg) }
override fun transform(expr: KBvAddExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvadd) }
override fun transform(expr: KBvSubExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvsub) }
override fun transform(expr: KBvMulExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvmul) }
override fun transform(expr: KBvUnsignedDivExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvudiv) }
override fun transform(expr: KBvSignedDivExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvsdiv) }
override fun transform(expr: KBvUnsignedRemExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvurem) }
override fun transform(expr: KBvSignedRemExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvsrem) }
override fun transform(expr: KBvSignedModExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvsmod) }
override fun transform(expr: KBvUnsignedLessExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvult) }
override fun transform(expr: KBvSignedLessExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvslt) }
override fun transform(expr: KBvUnsignedLessOrEqualExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvule) }
override fun transform(expr: KBvSignedLessOrEqualExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvsle) }
override fun transform(expr: KBvUnsignedGreaterOrEqualExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvuge) }
override fun transform(expr: KBvSignedGreaterOrEqualExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvsge) }
override fun transform(expr: KBvUnsignedGreaterExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvugt) }
override fun transform(expr: KBvSignedGreaterExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvsgt) }
override fun transform(expr: KBvConcatExpr): KExpr =
with(expr) { transform(arg0, arg1, Native::mkConcat) }
override fun transform(expr: KBvExtractExpr) = with(expr) {
transform(value) { value: Long -> Native.mkExtract(nCtx, high, low, value) }
}
override fun transform(expr: KBvSignExtensionExpr) = with(expr) {
transform(value) { value: Long -> Native.mkSignExt(nCtx, extensionSize, value) }
}
override fun transform(expr: KBvZeroExtensionExpr) = with(expr) {
transform(value) { value: Long -> Native.mkZeroExt(nCtx, extensionSize, value) }
}
override fun transform(expr: KBvRepeatExpr) = with(expr) {
transform(value) { value: Long -> Native.mkRepeat(nCtx, repeatNumber, value) }
}
override fun transform(expr: KBvShiftLeftExpr) =
with(expr) { transform(arg, shift, Native::mkBvshl) }
override fun transform(expr: KBvLogicalShiftRightExpr) =
with(expr) { transform(arg, shift, Native::mkBvlshr) }
override fun transform(expr: KBvArithShiftRightExpr) =
with(expr) { transform(arg, shift, Native::mkBvashr) }
override fun transform(expr: KBvRotateLeftExpr) =
with(expr) { transform(arg, rotation, Native::mkExtRotateLeft) }
override fun transform(expr: KBvRotateLeftIndexedExpr) = with(expr) {
transform(value) { value: Long -> Native.mkRotateLeft(nCtx, rotationNumber, value) }
}
override fun transform(expr: KBvRotateRightExpr) =
with(expr) { transform(arg, rotation, Native::mkExtRotateRight) }
override fun transform(expr: KBvRotateRightIndexedExpr) = with(expr) {
transform(value) { value: Long -> Native.mkRotateRight(nCtx, rotationNumber, value) }
}
override fun transform(expr: KBv2IntExpr) = with(expr) {
transform(value) { value: Long -> Native.mkBv2int(nCtx, value, isSigned) }
}
override fun transform(expr: KBvAddNoOverflowExpr) = with(expr) {
transform(arg0, arg1) { a0: Long, a1: Long ->
Native.mkBvaddNoOverflow(nCtx, a0, a1, isSigned)
}
}
override fun transform(expr: KBvAddNoUnderflowExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvaddNoUnderflow) }
override fun transform(expr: KBvSubNoOverflowExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvsubNoOverflow) }
override fun transform(expr: KBvSubNoUnderflowExpr) = with(expr) {
transform(arg0, arg1) { a0: Long, a1: Long ->
Native.mkBvsubNoUnderflow(nCtx, a0, a1, isSigned)
}
}
override fun transform(expr: KBvDivNoOverflowExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvsdivNoOverflow) }
override fun transform(expr: KBvNegNoOverflowExpr) =
with(expr) { transform(value, Native::mkBvnegNoOverflow) }
override fun transform(expr: KBvMulNoOverflowExpr) = with(expr) {
transform(arg0, arg1) { a0: Long, a1: Long ->
Native.mkBvmulNoOverflow(nCtx, a0, a1, isSigned)
}
}
override fun transform(expr: KBvMulNoUnderflowExpr) =
with(expr) { transform(arg0, arg1, Native::mkBvmulNoUnderflow) }
override fun transform(expr: KFp16Value): KExpr = expr.transform {
val sort = expr.sort.internalizeSort()
Native.mkFpaNumeralFloat(nCtx, expr.value, sort)
}
override fun transform(expr: KFp32Value): KExpr = expr.transform {
val sort = expr.sort.internalizeSort()
Native.mkFpaNumeralFloat(nCtx, expr.value, sort)
}
override fun transform(expr: KFp64Value): KExpr = expr.transform {
val sort = expr.sort.internalizeSort()
Native.mkFpaNumeralDouble(nCtx, expr.value, sort)
}
override fun transform(expr: KFp128Value): KExpr = with(expr) {
transform(ctx.mkBv(signBit), biasedExponent, significand, Native::mkFpaFp)
}
override fun transform(expr: KFpCustomSizeValue): KExpr = with(expr) {
transform(ctx.mkBv(signBit), biasedExponent, significand, Native::mkFpaFp)
}
override fun transform(expr: KFpRoundingModeExpr): KExpr = with(expr) {
transform { transformRoundingModeNumeral(value) }
}
override fun transform(expr: KFpAbsExpr): KExpr = with(expr) {
transform(value, Native::mkFpaAbs)
}
override fun transform(expr: KFpNegationExpr): KExpr = with(expr) {
transform(value, Native::mkFpaNeg)
}
override fun transform(expr: KFpAddExpr): KExpr = with(expr) {
transform(roundingMode, arg0, arg1, Native::mkFpaAdd)
}
override fun transform(expr: KFpSubExpr): KExpr = with(expr) {
transform(roundingMode, arg0, arg1, Native::mkFpaSub)
}
override fun transform(expr: KFpMulExpr): KExpr = with(expr) {
transform(roundingMode, arg0, arg1, Native::mkFpaMul)
}
override fun transform(expr: KFpDivExpr): KExpr = with(expr) {
transform(roundingMode, arg0, arg1, Native::mkFpaDiv)
}
override fun transform(expr: KFpFusedMulAddExpr): KExpr =
with(expr) {
transform(roundingMode, arg0, arg1, arg2, Native::mkFpaFma)
}
override fun transform(expr: KFpSqrtExpr): KExpr =
with(expr) {
transform(roundingMode, value, Native::mkFpaSqrt)
}
override fun transform(expr: KFpRemExpr): KExpr = with(expr) {
transform(arg0, arg1, Native::mkFpaRem)
}
override fun transform(expr: KFpRoundToIntegralExpr): KExpr =
with(expr) {
transform(roundingMode, value, Native::mkFpaRoundToIntegral)
}
override fun transform(expr: KFpMinExpr): KExpr = with(expr) {
transform(arg0, arg1, Native::mkFpaMin)
}
override fun transform(expr: KFpMaxExpr): KExpr = with(expr) {
transform(arg0, arg1, Native::mkFpaMax)
}
override fun transform(expr: KFpLessOrEqualExpr): KExpr = with(expr) {
transform(arg0, arg1, Native::mkFpaLeq)
}
override fun transform(expr: KFpLessExpr): KExpr = with(expr) {
transform(arg0, arg1, Native::mkFpaLt)
}
override fun transform(expr: KFpGreaterOrEqualExpr): KExpr = with(expr) {
transform(arg0, arg1, Native::mkFpaGeq)
}
override fun transform(expr: KFpGreaterExpr): KExpr = with(expr) {
transform(arg0, arg1, Native::mkFpaGt)
}
override fun transform(expr: KFpEqualExpr): KExpr = with(expr) {
transform(arg0, arg1, Native::mkFpaEq)
}
override fun transform(expr: KFpIsNormalExpr): KExpr = with(expr) {
transform(value, Native::mkFpaIsNormal)
}
override fun transform(expr: KFpIsSubnormalExpr): KExpr = with(expr) {
transform(value, Native::mkFpaIsSubnormal)
}
override fun transform(expr: KFpIsZeroExpr): KExpr = with(expr) {
transform(value, Native::mkFpaIsZero)
}
override fun transform(expr: KFpIsInfiniteExpr): KExpr = with(expr) {
transform(value, Native::mkFpaIsInfinite)
}
override fun transform(expr: KFpIsNaNExpr): KExpr = with(expr) {
transform(value, Native::mkFpaIsNan)
}
override fun transform(expr: KFpIsNegativeExpr): KExpr = with(expr) {
transform(value, Native::mkFpaIsNegative)
}
override fun transform(expr: KFpIsPositiveExpr): KExpr = with(expr) {
transform(value, Native::mkFpaIsPositive)
}
override fun transform(expr: KFpToBvExpr): KExpr =
with(expr) {
transform(roundingMode, value) { rm: Long, value: Long ->
if (isSigned) {
Native.mkFpaToSbv(nCtx, rm, value, bvSize)
} else {
Native.mkFpaToUbv(nCtx, rm, value, bvSize)
}
}
}
private fun transformRoundingModeNumeral(roundingMode: KFpRoundingMode): Long =
when (roundingMode) {
KFpRoundingMode.RoundNearestTiesToEven -> Native.mkFpaRoundNearestTiesToEven(nCtx)
KFpRoundingMode.RoundNearestTiesToAway -> Native.mkFpaRoundNearestTiesToAway(nCtx)
KFpRoundingMode.RoundTowardNegative -> Native.mkFpaRoundTowardNegative(nCtx)
KFpRoundingMode.RoundTowardPositive -> Native.mkFpaRoundTowardPositive(nCtx)
KFpRoundingMode.RoundTowardZero -> Native.mkFpaRoundTowardZero(nCtx)
}
override fun transform(expr: KFpToRealExpr): KExpr = with(expr) {
transform(value, Native::mkFpaToReal)
}
override fun transform(expr: KFpToIEEEBvExpr): KExpr = with(expr) {
transform(value, Native::mkFpaToIeeeBv)
}
override fun transform(expr: KFpFromBvExpr): KExpr = with(expr) {
transform(sign, biasedExponent, significand, Native::mkFpaFp)
}
override fun transform(expr: KFpToFpExpr): KExpr = with(expr) {
transform(roundingMode, value) { rm: Long, value: Long ->
val fpSort = sort.internalizeSort()
Native.mkFpaToFpFloat(nCtx, rm, value, fpSort)
}
}
override fun transform(expr: KRealToFpExpr): KExpr = with(expr) {
transform(roundingMode, value) { rm: Long, value: Long ->
val fpSort = sort.internalizeSort()
Native.mkFpaToFpReal(nCtx, rm, value, fpSort)
}
}
override fun transform(expr: KBvToFpExpr): KExpr = with(expr) {
transform(roundingMode, value) { rm: Long, value: Long ->
val fpSort = sort.internalizeSort()
if (signed) {
Native.mkFpaToFpSigned(nCtx, rm, value, fpSort)
} else {
Native.mkFpaToFpUnsigned(nCtx, rm, value, fpSort)
}
}
}
override fun transform(expr: KArrayStore) = with(expr) {
transform(array, index, value, Native::mkStore)
}
override fun transform(
expr: KArray2Store
): KExpr> = with(expr) {
transform(array, index0, index1, value) { array: Long, i0: Long, i1: Long, value: Long ->
val indices = longArrayOf(i0, i1)
Native.mkStoreN(nCtx, array, indices.size, indices, value)
}
}
override fun transform(
expr: KArray3Store
): KExpr> = with(expr) {
transformArray(listOf(array, index0, index1, index2, value)) { args ->
val (array, i0, i1, i2, value) = args
val indices = longArrayOf(i0, i1, i2)
Native.mkStoreN(nCtx, array, indices.size, indices, value)
}
}
override fun transform(expr: KArrayNStore): KExpr> = with(expr) {
transformArray(indices + listOf(array, value)) { args ->
val value = args[args.lastIndex]
val array = args[args.lastIndex - 1]
val indices = args.copyOf(args.size - 2)
Native.mkStoreN(nCtx, array, indices.size, indices, value)
}
}
override fun transform(expr: KArraySelect) = with(expr) {
transform(array, index, Native::mkSelect)
}
override fun transform(
expr: KArray2Select
): KExpr = with(expr) {
transform(array, index0, index1) { array: Long, i0: Long, i1: Long ->
val indices = longArrayOf(i0, i1)
Native.mkSelectN(nCtx, array, indices.size, indices)
}
}
override fun transform(
expr: KArray3Select
): KExpr = with(expr) {
transform(array, index0, index1, index2) { array: Long, i0: Long, i1: Long, i2: Long ->
val indices = longArrayOf(i0, i1, i2)
Native.mkSelectN(nCtx, array, indices.size, indices)
}
}
override fun transform(expr: KArrayNSelect): KExpr = with(expr) {
transformArray(indices + array) { args ->
val array = args.last()
val indices = args.copyOf(args.size - 1)
Native.mkSelectN(nCtx, array, indices.size, indices)
}
}
override fun , R : KSort> transform(expr: KArrayConst) = with(expr) {
transform(value) { value: Long ->
mkConstArray(sort, value)
}
}
private fun mkConstArray(sort: KArraySortBase<*>, value: Long): Long =
if (sort is KArraySort<*, *>) {
Native.mkConstArray(nCtx, sort.domain.internalizeSort(), value)
} else {
ensureArraySortInternalized(sort)
val domain = sort.domainSorts.let { domain ->
LongArray(domain.size) { domain[it].internalizeSort() }
}
val domainNames = LongArray(sort.domainSorts.size) { Native.mkIntSymbol(nCtx, it) }
Native.mkLambda(nCtx, domain.size, domain, domainNames, value)
}
override fun transform(expr: KArrayLambda) = with(expr) {
transform(body, ctx.mkConstApp(indexVarDecl)) { body: Long, index: Long ->
ensureArraySortInternalized(expr.sort)
val indices = longArrayOf(index)
Native.mkLambdaConst(nCtx, indices.size, indices, body)
}
}
override fun transform(
expr: KArray2Lambda
): KExpr> = with(expr) {
transform(
body, ctx.mkConstApp(indexVar0Decl), ctx.mkConstApp(indexVar1Decl)
) { body: Long, index0: Long, index1: Long ->
ensureArraySortInternalized(expr.sort)
val indices = longArrayOf(index0, index1)
Native.mkLambdaConst(nCtx, indices.size, indices, body)
}
}
override fun transform(
expr: KArray3Lambda
): KExpr> = with(expr) {
transform(
body, ctx.mkConstApp(indexVar0Decl), ctx.mkConstApp(indexVar1Decl), ctx.mkConstApp(indexVar2Decl)
) { body: Long, index0: Long, index1: Long, index2: Long ->
ensureArraySortInternalized(expr.sort)
val indices = longArrayOf(index0, index1, index2)
Native.mkLambdaConst(nCtx, indices.size, indices, body)
}
}
override fun transform(expr: KArrayNLambda): KExpr> = with(expr) {
transformArray(indexVarDeclarations.map { ctx.mkConstApp(it) } + body) { args ->
ensureArraySortInternalized(expr.sort)
val body = args.last()
val indices = args.copyOf(args.size - 1)
Native.mkLambdaConst(nCtx, indices.size, indices, body)
}
}
/**
* Z3 incorrectly manage array sort references on lambda expression creation.
* If the created lambda expression is the only reference to the array sort,
* it results in native error on context deletion. To bypass this issue
* we ensure that array sort is referenced not only in the created lambda
* */
private fun ensureArraySortInternalized(sort: KArraySortBase<*>) {
sort.internalizeSort()
}
override fun transform(expr: KAddArithExpr) = with(expr) {
transformArray(args) { args -> Native.mkAdd(nCtx, args.size, args) }
}
override fun transform(expr: KSubArithExpr) = with(expr) {
transformArray(args) { args -> Native.mkSub(nCtx, args.size, args) }
}
override fun transform(expr: KMulArithExpr) = with(expr) {
transformArray(args) { args -> Native.mkMul(nCtx, args.size, args) }
}
override fun transform(expr: KUnaryMinusArithExpr) = with(expr) {
transform(arg, Native::mkUnaryMinus)
}
override fun transform(expr: KDivArithExpr) = with(expr) {
transform(lhs, rhs, Native::mkDiv)
}
override fun transform(expr: KPowerArithExpr) = with(expr) {
transform(lhs, rhs, Native::mkPower)
}
override fun transform(expr: KLtArithExpr) = with(expr) { transform(lhs, rhs, Native::mkLt) }
override fun transform(expr: KLeArithExpr) = with(expr) { transform(lhs, rhs, Native::mkLe) }
override fun transform(expr: KGtArithExpr) = with(expr) { transform(lhs, rhs, Native::mkGt) }
override fun transform(expr: KGeArithExpr