Skip to content

Commit 29e0d77

Browse files
committed
Create ApplicationBlockGraph interface, jvm implementation
1 parent f37c4e6 commit 29e0d77

File tree

19 files changed

+1403
-0
lines changed

19 files changed

+1403
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ buildSrc/.gradle
88

99
# Ignore Idea directory
1010
.idea
11+
12+
# Ignore MacOS-specific files
13+
/**/.DS_Store

buildSrc/src/main/kotlin/Versions.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ object Versions {
88
const val mockk = "1.13.4"
99
const val junitParams = "5.9.3"
1010
const val logback = "1.4.8"
11+
const val onnxruntime = "1.15.1"
1112

1213
// versions for jvm samples
1314
const val samplesLombok = "1.18.20"

buildSrc/src/main/kotlin/usvm.kotlin-conventions.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ dependencies {
1919

2020
implementation(kotlin("stdlib-jdk8"))
2121
implementation(kotlin("reflect"))
22+
implementation("com.microsoft.onnxruntime", "onnxruntime", Versions.onnxruntime)
2223
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.coroutines}")
2324

2425
testImplementation(kotlin("test"))

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ include("usvm-core")
44
include("usvm-jvm")
55
include("usvm-util")
66
include("usvm-sample-language")
7+
include("usvm-ml-path-selection")

usvm-core/src/main/kotlin/org/usvm/PathTrieNode.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ sealed class PathsTrieNode<State : UState<*, *, Statement, *, *, State>, Stateme
3434
*/
3535
abstract val depth: Int
3636

37+
/**
38+
* States that were forked from this node
39+
*/
40+
abstract val accumulatedForks: MutableCollection<State>
41+
3742
/**
3843
* Adds a new label to [labels] collection.
3944
*/
@@ -80,6 +85,7 @@ class PathsTrieNodeImpl<State : UState<*, *, Statement, *, *, State>, Statement>
8085
statement = statement
8186
) {
8287
parentNode.children[statement] = this
88+
parentNode.accumulatedForks.addAll(this.states)
8389
}
8490

8591
internal constructor(parentNode: PathsTrieNodeImpl<State, Statement>, statement: Statement, state: State) : this(
@@ -89,11 +95,14 @@ class PathsTrieNodeImpl<State : UState<*, *, Statement, *, *, State>, Statement>
8995
statement = statement
9096
) {
9197
parentNode.children[statement] = this
98+
parentNode.accumulatedForks.addAll(this.states)
9299
parentNode.states -= state
93100
}
94101

95102
override val labels: MutableSet<Any> = hashSetOf()
96103

104+
override val accumulatedForks: MutableCollection<State> = mutableSetOf()
105+
97106
override fun addLabel(label: Any) {
98107
labels.add(label)
99108
}
@@ -115,6 +124,8 @@ class RootNode<State : UState<*, *, Statement, *, *, State>, Statement> : PathsT
115124

116125
override val labels: MutableSet<Any> = hashSetOf()
117126

127+
override val accumulatedForks: MutableCollection<State> = mutableSetOf()
128+
118129
override val depth: Int = 0
119130

120131
override fun addLabel(label: Any) {

usvm-core/src/main/kotlin/org/usvm/statistics/CoverageStatistics.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ class CoverageStatistics<Method, Statement, State : UState<*, Method, Statement,
8989
return uncoveredStatements.values.flatten()
9090
}
9191

92+
fun isCovered(statement: Statement) = statement in coveredStatements.values.flatten()
93+
94+
fun inCoverageZone(method: Method) = coveredStatements.containsKey(method) || uncoveredStatements.containsKey(method)
95+
9296
/**
9397
* Adds a listener triggered when a new statement is covered.
9498
*/
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
plugins {
2+
id("usvm.kotlin-conventions")
3+
}
4+
5+
dependencies {
6+
implementation(project(":usvm-core"))
7+
implementation(project(":usvm-jvm"))
8+
9+
implementation("org.jacodb:jacodb-analysis:${Versions.jcdb}")
10+
implementation("org.jacodb:jacodb-approximations:${Versions.jcdb}")
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.usvm
2+
3+
import org.usvm.statistics.ApplicationGraph
4+
5+
interface ApplicationBlockGraph<Method, BasicBlock, Statement> : ApplicationGraph<Method, BasicBlock> {
6+
fun blockOf(stmt: Statement): BasicBlock
7+
fun instructions(block: BasicBlock): Sequence<Statement>
8+
fun blocks(): Sequence<BasicBlock>
9+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.usvm
2+
3+
enum class MLPathSelectionStrategy {
4+
/**
5+
* Collects features according to states selected by any other path selector.
6+
*/
7+
FEATURES_LOGGING,
8+
9+
/**
10+
* Collects features and feeds them to the ML model to select states.
11+
* Extends FEATURE_LOGGING path selector.
12+
*/
13+
MACHINE_LEARNING,
14+
15+
/**
16+
* Selects states with best Graph Neural Network state score
17+
*/
18+
GNN,
19+
}
20+
21+
data class MLMachineOptions(
22+
val basicOptions: UMachineOptions,
23+
val pathSelectionStrategy: MLPathSelectionStrategy,
24+
val heteroGNNModelPath: String = ""
25+
)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.usvm
2+
3+
import org.usvm.ps.ExceptionPropagationPathSelector
4+
import org.usvm.ps.GNNPathSelector
5+
import org.usvm.statistics.CoverageStatistics
6+
import org.usvm.statistics.StateVisitsStatistics
7+
8+
fun <Method, Statement, BasicBlock, State : UState<*, Method, Statement, *, *, State>> createPathSelector(
9+
initialState: State,
10+
options: MLMachineOptions,
11+
applicationGraph: ApplicationBlockGraph<Method, BasicBlock, Statement>,
12+
stateVisitsStatistics: StateVisitsStatistics<Method, Statement, State>,
13+
coverageStatistics: CoverageStatistics<Method, Statement, State>,
14+
): UPathSelector<State> {
15+
val selector = when (options.pathSelectionStrategy) {
16+
MLPathSelectionStrategy.GNN -> createGNNPathSelector(
17+
stateVisitsStatistics,
18+
coverageStatistics, applicationGraph, options.heteroGNNModelPath
19+
)
20+
21+
else -> {
22+
throw NotImplementedError()
23+
}
24+
}
25+
26+
val propagateExceptions = options.basicOptions.exceptionsPropagation
27+
28+
val resultSelector = selector.wrapIfRequired(propagateExceptions)
29+
resultSelector.add(listOf(initialState))
30+
31+
return selector
32+
}
33+
34+
private fun <State : UState<*, *, *, *, *, State>> UPathSelector<State>.wrapIfRequired(propagateExceptions: Boolean) =
35+
if (propagateExceptions && this !is ExceptionPropagationPathSelector<State>) {
36+
ExceptionPropagationPathSelector(this)
37+
} else {
38+
this
39+
}
40+
41+
private fun <Method, Statement, BasicBlock, State : UState<*, Method, Statement, *, *, State>> createGNNPathSelector(
42+
stateVisitsStatistics: StateVisitsStatistics<Method, Statement, State>,
43+
coverageStatistics: CoverageStatistics<Method, Statement, State>,
44+
applicationGraph: ApplicationBlockGraph<Method, BasicBlock, Statement>,
45+
heteroGNNModelPath: String,
46+
): UPathSelector<State> {
47+
return GNNPathSelector(
48+
coverageStatistics,
49+
stateVisitsStatistics,
50+
applicationGraph,
51+
heteroGNNModelPath
52+
)
53+
}

0 commit comments

Comments
 (0)