Skip to content

Commit ea730e0

Browse files
authored
Optimize solver cloning (#12)
1 parent aac1acd commit ea730e0

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

utbot-framework/src/main/kotlin/org/utbot/engine/ExecutionState.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import kotlinx.collections.immutable.persistentHashMapOf
1212
import kotlinx.collections.immutable.persistentHashSetOf
1313
import kotlinx.collections.immutable.persistentListOf
1414
import kotlinx.collections.immutable.plus
15+
import org.utbot.engine.pc.UtSolverStatusUNDEFINED
1516
import soot.SootMethod
1617
import soot.jimple.Stmt
1718

@@ -205,6 +206,15 @@ data class ExecutionState(
205206
)
206207
}
207208

209+
/**
210+
* Tell to solver that states with status [UtSolverStatusUNDEFINED] can be created from current state.
211+
*
212+
* Note: Solver optimize cloning respect this flag.
213+
*/
214+
fun expectUndefined() {
215+
solver.expectUndefined = true
216+
}
217+
208218
override fun close() {
209219
solver.close()
210220
}

utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,6 +1370,7 @@ class UtBotSymbolicEngine(
13701370
val negativeCasePathConstraint = mkNot(positiveCasePathConstraint)
13711371

13721372
positiveCaseEdge?.let { edge ->
1373+
environment.state.expectUndefined()
13731374
val positiveCaseState = environment.state.updateQueued(
13741375
edge,
13751376
SymbolicStateUpdate(
@@ -1435,6 +1436,9 @@ class UtBotSymbolicEngine(
14351436
}
14361437
else -> error("Unknown switch $current")
14371438
}
1439+
if (successors.size > 1) {
1440+
environment.state.expectUndefined()
1441+
}
14381442
successors.forEach { (target, expr) ->
14391443
pathSelector.offer(
14401444
environment.state.updateQueued(
@@ -3432,6 +3436,7 @@ class UtBotSymbolicEngine(
34323436

34333437
val symException = implicitThrown(exception, findNewAddr(), isInNestedMethod())
34343438
if (!traverseCatchBlock(environment.state.stmt, symException, conditions)) {
3439+
environment.state.expectUndefined()
34353440
val nextState = environment.state.createExceptionState(
34363441
symException,
34373442
queuedSymbolicStateUpdates

utbot-framework/src/main/kotlin/org/utbot/engine/pc/UtSolver.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,13 @@ data class UtSolver constructor(
161161
val assertions: Set<UtBoolExpression>
162162
get(): Set<UtBoolExpression> = constraints.hard
163163

164+
var expectUndefined: Boolean = false
165+
164166
fun add(hard: HardConstraint, soft: SoftConstraint): UtSolver {
165167
// status can implicitly change here to UNDEFINED or UNSAT
166168
val newConstraints = constraints.with(hard.constraints, soft.constraints)
167-
/*
168-
Always there is at least one new state with SAT status if current status is SAT
169-
Thus we can prioritize states like this to reuse current solver.
170-
*/
171-
val isSAT = constraints.status is UtSolverStatusSAT
172-
val wantClone = (isSAT && newConstraints.status is UtSolverStatusSAT)
173-
|| (!isSAT && newConstraints !is UnsatQuery)
169+
val wantClone = (expectUndefined && newConstraints.status is UtSolverStatusUNDEFINED)
170+
|| (!expectUndefined && newConstraints.status !is UtSolverStatusUNSAT)
174171

175172
return if (wantClone && canBeCloned) {
176173
// try to reuse z3 Solver with value SAT when possible

0 commit comments

Comments
 (0)