Skip to content

Commit

Permalink
Core: avoid explosive flattening
Browse files Browse the repository at this point in the history
  • Loading branch information
Saloed committed Nov 1, 2023
1 parent 856455d commit a4dd431
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ interface KArrayExprSimplifier : KExprSimplifierBase {
val original: KExpr<A>,
val base: KExpr<A>,
val values: List<KExpr<R>>
) : KExpr<A>(ctx) {
) : KExpr<A>(ctx), KSimplifierAuxExpr {
override val sort: A
get() = base.sort

Expand Down Expand Up @@ -1146,7 +1146,7 @@ interface KArrayExprSimplifier : KExprSimplifierBase {
private sealed class SimplifierArraySelectBaseExpr<A : KArraySortBase<R>, R : KSort>(
ctx: KContext,
val array: KExpr<A>
) : KExpr<R>(ctx) {
) : KExpr<R>(ctx), KSimplifierAuxExpr {
override val sort: R
get() = array.sort.range

Expand Down Expand Up @@ -1217,7 +1217,7 @@ interface KArrayExprSimplifier : KExprSimplifierBase {
private sealed class SelectFromStoreExprBase<A : KArraySortBase<R>, R : KSort>(
ctx: KContext,
array: KArrayStoreBase<A, R>
) : KExpr<R>(ctx) {
) : KExpr<R>(ctx), KSimplifierAuxExpr {
val storeValue: KExpr<R> = array.value

override val sort: R = storeValue.sort
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import io.ksmt.expr.KXorExpr
import io.ksmt.expr.transformer.KTransformerBase
import io.ksmt.sort.KBoolSort
import io.ksmt.sort.KSort
import java.util.IdentityHashMap

interface KBoolExprSimplifier : KExprSimplifierBase {

Expand Down Expand Up @@ -213,7 +214,7 @@ interface KBoolExprSimplifier : KExprSimplifierBase {
val condition: KExpr<KBoolSort>,
val trueBranch: KExpr<T>,
val falseBranch: KExpr<T>
) : KApp<T, KBoolSort>(ctx) {
) : KApp<T, KBoolSort>(ctx), KSimplifierAuxExpr {

override val decl: KDecl<T>
get() = ctx.mkIteDecl(trueBranch.sort)
Expand All @@ -240,7 +241,7 @@ interface KBoolExprSimplifier : KExprSimplifierBase {
val simplifiedCondition: KExpr<KBoolSort>,
val trueBranch: KExpr<T>,
val falseBranch: KExpr<T>
) : KApp<T, T>(ctx) {
) : KApp<T, T>(ctx), KSimplifierAuxExpr {

override val decl: KDecl<T>
get() = ctx.mkIteDecl(trueBranch.sort)
Expand Down Expand Up @@ -272,7 +273,7 @@ interface KBoolExprSimplifier : KExprSimplifierBase {
val neutralElement: KExpr<KBoolSort>,
val zeroElement: KExpr<KBoolSort>,
override val args: List<KExpr<KBoolSort>>
) : KApp<KBoolSort, KBoolSort>(ctx) {
) : KApp<KBoolSort, KBoolSort>(ctx), KSimplifierAuxExpr {
override val sort: KBoolSort = ctx.boolSort
override val decl: KDecl<KBoolSort>
get() = when (operation) {
Expand All @@ -287,6 +288,7 @@ interface KBoolExprSimplifier : KExprSimplifierBase {

val simplifiedArgs = arrayListOf<KExpr<KBoolSort>>()

private val visitedArgs = IdentityHashMap<KExpr<*>, Unit>()
private val argsIteratorStack = arrayListOf(args.iterator())
private var currentArgument: KExpr<KBoolSort>? = null

Expand All @@ -309,6 +311,9 @@ interface KBoolExprSimplifier : KExprSimplifierBase {

while (hasUnprocessedArgument()) {
val argument = argsIteratorStack.last().next()

if (visitedArgs.put(argument, Unit) != null) continue

if (!tryFlatExpr(argument)) {
currentArgument = argument
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1083,7 +1083,7 @@ interface KBvExprSimplifier : KExprSimplifierBase {
private class SimplifierFlatBvAddExpr<T : KBvSort>(
ctx: KContext,
override val args: List<KExpr<T>>
) : KApp<T, T>(ctx) {
) : KApp<T, T>(ctx), KSimplifierAuxExpr {

override val decl: KDecl<T>
get() = ctx.mkBvAddDecl(sort, sort)
Expand All @@ -1104,7 +1104,7 @@ interface KBvExprSimplifier : KExprSimplifierBase {
private class SimplifierFlatBvMulExpr<T : KBvSort>(
ctx: KContext,
override val args: List<KExpr<T>>
) : KApp<T, T>(ctx) {
) : KApp<T, T>(ctx), KSimplifierAuxExpr {

override val decl: KDecl<T>
get() = ctx.mkBvMulDecl(sort, sort)
Expand All @@ -1125,7 +1125,7 @@ interface KBvExprSimplifier : KExprSimplifierBase {
private class SimplifierFlatBvOrExpr<T : KBvSort>(
ctx: KContext,
override val args: List<KExpr<T>>
) : KApp<T, T>(ctx) {
) : KApp<T, T>(ctx), KSimplifierAuxExpr {

override val decl: KDecl<T>
get() = ctx.mkBvOrDecl(sort, sort)
Expand All @@ -1146,7 +1146,7 @@ interface KBvExprSimplifier : KExprSimplifierBase {
private class SimplifierFlatBvAndExpr<T : KBvSort>(
ctx: KContext,
override val args: List<KExpr<T>>
) : KApp<T, T>(ctx) {
) : KApp<T, T>(ctx), KSimplifierAuxExpr {

override val decl: KDecl<T>
get() = ctx.mkBvAndDecl(sort, sort)
Expand All @@ -1167,7 +1167,7 @@ interface KBvExprSimplifier : KExprSimplifierBase {
private class SimplifierFlatBvXorExpr<T : KBvSort>(
ctx: KContext,
override val args: List<KExpr<T>>
) : KApp<T, T>(ctx) {
) : KApp<T, T>(ctx), KSimplifierAuxExpr {

override val decl: KDecl<T>
get() = ctx.mkBvXorDecl(sort, sort)
Expand All @@ -1189,7 +1189,7 @@ interface KBvExprSimplifier : KExprSimplifierBase {
ctx: KContext,
override val sort: KBvSort,
override val args: List<KExpr<KBvSort>>
) : KApp<KBvSort, KBvSort>(ctx) {
) : KApp<KBvSort, KBvSort>(ctx), KSimplifierAuxExpr {

// We have no decl, but we don't care since decl is unused
override val decl: KDecl<KBvSort>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,10 @@ open class KExprSimplifier(override val ctx: KContext) :
val result = transformedExpr(rewriteFrame.rewritten)
?: error("Nested rewrite failed")

if (rewriteFrame.rewritten is KSimplifierAuxExpr) {
eraseTransformationResult(rewriteFrame.rewritten)
}

return result.uncheckedCast()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ interface KExprSimplifierBase : KTransformer {
@JvmInline
internal value class SimplifierAuxExpression<T : KSort>(val expr: KExpr<T>)

/**
* Mark simplifier auxiliary expressions.
* */
internal interface KSimplifierAuxExpr

internal inline fun <T : KSort> auxExpr(builder: () -> KExpr<T>): SimplifierAuxExpression<T> =
SimplifierAuxExpression(builder())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ abstract class KNonRecursiveTransformerBase: KTransformer {
return transformed[expr] as? KExpr<T>
}

/**
* Erase [expr] transformation result.
* Useful for transformer auxiliary expressions.
* */
fun eraseTransformationResult(expr: KExpr<*>) {
transformed.remove(expr)
}

/**
* Allows to skip expression transformation and stop deepening.
* */
Expand Down

0 comments on commit a4dd431

Please sign in to comment.