11package org.usvm
22
33import io.ksmt.expr.KInterpretedValue
4+ import kotlinx.collections.immutable.PersistentList
5+ import kotlinx.collections.immutable.toPersistentList
46import org.usvm.constraints.UPathConstraints
57import org.usvm.memory.UMemory
68import org.usvm.model.UModelBase
@@ -10,15 +12,18 @@ import org.usvm.solver.UUnsatResult
1012
1113typealias StateId = UInt
1214
13- abstract class UState <Type , Method , Statement , Context : UContext , State : UState < Type , Method , Statement , Context , State > >(
15+ abstract class UState <Type , Method , Statement , Context , Target , State >(
1416 // TODO: add interpreter-specific information
1517 ctx : UContext ,
1618 open val callStack : UCallStack <Method , Statement >,
1719 open val pathConstraints : UPathConstraints <Type , Context >,
1820 open val memory : UMemory <Type , Method >,
1921 open var models : List <UModelBase <Type >>,
2022 open var pathLocation : PathsTrieNode <State , Statement >,
21- ) {
23+ targets : List <Target > = emptyList(),
24+ ) where Context : UContext,
25+ Target : UTarget <Statement , Target , State >,
26+ State : UState <Type , Method , Statement , Context , Target , State > {
2227 /* *
2328 * Deterministic state id.
2429 * TODO: Can be replaced with overridden hashCode
@@ -54,7 +59,7 @@ abstract class UState<Type, Method, Statement, Context : UContext, State : UStat
5459 if (this == = other) return true
5560 if (javaClass != other?.javaClass) return false
5661
57- other as UState <* , * , * , * , * >
62+ other as UState <* , * , * , * , * , * >
5863
5964 return id == other.id
6065 }
@@ -73,6 +78,46 @@ abstract class UState<Type, Method, Statement, Context : UContext, State : UStat
7378 * A property containing information about whether the state is exceptional or not.
7479 */
7580 abstract val isExceptional: Boolean
81+
82+ protected var targetsImpl: PersistentList <Target > = targets.toPersistentList()
83+ private set
84+
85+ private val reachedTerminalTargetsImpl = mutableSetOf<Target >()
86+
87+ /* *
88+ * Collection of state's current targets.
89+ * TODO: clean removed targets sometimes
90+ */
91+ val targets: Sequence <Target > get() = targetsImpl.asSequence().filterNot { it.isRemoved }
92+
93+ /* *
94+ * Reached targets with no children.
95+ */
96+ val reachedTerminalTargets: Set <Target > = reachedTerminalTargetsImpl
97+
98+ /* *
99+ * If the [target] is not removed and is contained in this state's target collection,
100+ * removes it from there and adds there all its children.
101+ *
102+ * @return true if the [target] was successfully removed.
103+ */
104+ internal fun tryPropagateTarget (target : Target ): Boolean {
105+ val previousTargetCount = targetsImpl.size
106+ targetsImpl = targetsImpl.remove(target)
107+
108+ if (previousTargetCount == targetsImpl.size || ! target.isRemoved) {
109+ return false
110+ }
111+
112+ if (target.isTerminal) {
113+ reachedTerminalTargetsImpl.add(target)
114+ return true
115+ }
116+
117+ targetsImpl = targetsImpl.addAll(target.children)
118+
119+ return true
120+ }
76121}
77122
78123data class ForkResult <T >(
@@ -96,7 +141,7 @@ private const val OriginalState = false
96141 * forked state.
97142 *
98143 */
99- private fun <T : UState <Type , * , * , Context , T >, Type , Context : UContext > forkIfSat (
144+ private fun <T : UState <Type , * , * , Context , * , T >, Type , Context : UContext > forkIfSat (
100145 state : T ,
101146 newConstraintToOriginalState : UBoolExpr ,
102147 newConstraintToForkedState : UBoolExpr ,
@@ -156,7 +201,7 @@ private fun <T : UState<Type, *, *, Context, T>, Type, Context : UContext> forkI
156201 * 2. makes not more than one query to USolver;
157202 * 3. if both [condition] and ![condition] are satisfiable, then [ForkResult.positiveState] === [state].
158203 */
159- fun <T : UState <Type , * , * , Context , T >, Type , Context : UContext > fork (
204+ fun <T : UState <Type , * , * , Context , * , T >, Type , Context : UContext > fork (
160205 state : T ,
161206 condition : UBoolExpr ,
162207): ForkResult <T > {
@@ -217,7 +262,7 @@ fun <T : UState<Type, *, *, Context, T>, Type, Context : UContext> fork(
217262 * @return a list of states for each condition - `null` state
218263 * means [UUnknownResult] or [UUnsatResult] of checking condition.
219264 */
220- fun <T : UState <Type , * , * , Context , T >, Type , Context : UContext > forkMulti (
265+ fun <T : UState <Type , * , * , Context , * , T >, Type , Context : UContext > forkMulti (
221266 state : T ,
222267 conditions : Iterable <UBoolExpr >,
223268): List <T ?> {
0 commit comments