Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
264 commits
Select commit Hold shift + click to select a range
bc73864
Fix --no-sa option
solid-eureka Sep 2, 2026
207d6a7
Enhance logging for static pre-analysis and update config file handli…
solid-eureka Sep 3, 2026
27e5a11
Refactor SANode and add exceptional child handling
solid-eureka Sep 3, 2026
84cc7d0
Remove duplicate call to checkAndSetBranch in visitIF_ACMPEQ
solid-eureka Sep 4, 2026
9c8047e
Add more SA stats logging
solid-eureka Sep 7, 2026
e77bddb
TEST: Prevent false SAFE classifications.
solid-eureka Sep 7, 2026
a88eb78
Log current commit when running sv-comp
solid-eureka Sep 8, 2026
e8c0e4f
Use different strategy of preventing false SAFE classifications
solid-eureka Sep 8, 2026
ee415f4
Add shorthand notation for comparing results
solid-eureka Sep 10, 2026
7da5083
Add allowlist for class names beginning with 'L'
solid-eureka Sep 10, 2026
9872c26
Improve run analysis: Output performance metrics and merge similar er…
solid-eureka Sep 10, 2026
466cafc
Fix SMT solver timing and split out static pre-analysis stage
solid-eureka Sep 10, 2026
4c101c7
Cleanup debug code in SolverHandler.py
solid-eureka Sep 10, 2026
33ad778
Add --sa-retry-without option to gate failsafe behavior
solid-eureka Sep 19, 2026
18f2003
Implement StringValue.invokeIsEmpty()
solid-eureka Sep 19, 2026
9fd6bd7
Pass absolute classpath to CFG extractor
solid-eureka Sep 21, 2026
a026a54
Add virtual dispatch example
solid-eureka Sep 21, 2026
fab078a
Skip SA branch traversal inside static initializer blocks
solid-eureka Sep 21, 2026
3895cc9
Use logger for DFS
solid-eureka Sep 21, 2026
a5b6b6f
Increase SA timeout for SVComp
solid-eureka Sep 21, 2026
b40b409
Update notes
solid-eureka Sep 22, 2026
c98ded0
Add timeout option to SVComp script
solid-eureka Sep 24, 2026
e45ea2c
Improve error reporting for loading SA graphs
solid-eureka Sep 24, 2026
284b967
Fix SA graph traversal in DFS
solid-eureka Sep 24, 2026
5cc7462
Update handling of incomplete SA graphs
solid-eureka Sep 24, 2026
20183dd
Log argv when running SVComp
solid-eureka Sep 24, 2026
f671352
Consistent case_occurrences order in results.json files
solid-eureka Sep 26, 2026
d1fccf9
Stop echoing logs in parallel SVComp runs
solid-eureka Sep 26, 2026
2780fc3
Walk the static-analysis graph with a call stack
solid-eureka Sep 27, 2026
7f56b54
Add CLAUDE.md
solid-eureka Sep 27, 2026
0f1fff8
Stop printing the whole tree when running SAGraph.py directly
solid-eureka Sep 27, 2026
7c54640
WIP: Runtime comparison plots
solid-eureka Sep 27, 2026
dd454f6
More runtime comparison plots
solid-eureka Sep 27, 2026
42e842c
Runtime plots as SVG
solid-eureka Sep 27, 2026
58f2291
Improve plot script ease-of-use
solid-eureka Sep 27, 2026
cc7f1eb
Add plot showing results as if static pre-analysis took no time
solid-eureka Sep 28, 2026
1610bbc
Add support for linear plots
solid-eureka Sep 28, 2026
1a5c545
Run static pre-analysis in the background during exploration
solid-eureka Sep 28, 2026
51d57d5
Rank branches by distance to an assert (--sa-rank-distance)
solid-eureka Sep 29, 2026
a0eba44
Encode char inputs as numbers
solid-eureka Sep 29, 2026
52679a0
Parse negative long inputs
solid-eureka Sep 29, 2026
434f262
Model Character predicates and case mappings
solid-eureka Sep 29, 2026
a99050e
Model String trim, compareTo, lastIndexOf, regionMatches and valueOf(…
solid-eureka Sep 29, 2026
984b3bd
Model Math floor/ceil/rint/toRadians/toDegrees/getExponent exactly an…
solid-eureka Sep 29, 2026
04a6413
Record bounds checks of untracked arrays as concrete-only branches
solid-eureka Sep 29, 2026
5ea26bc
Record context loss when an uninstrumented call with symbolic argumen…
solid-eureka Sep 29, 2026
6646e78
Wait for static pre-analysis by default; add --parallel-sa
solid-eureka Sep 29, 2026
4675078
Remove notes
solid-eureka Sep 29, 2026
15f0893
Log divergences from approximate-model solutions as expected
solid-eureka Sep 29, 2026
b3d687c
Add --solver-rlimit: escalating Z3 resource limits per branch
solid-eureka Sep 30, 2026
6e087b8
Switch to the latest SV-Benchmarks and keep the old suite
solid-eureka Sep 30, 2026
0a7e127
Note the local label fix for ReverseInterpolator_true
solid-eureka Sep 30, 2026
b7ae54f
Note the local label fixes for PieSegment_true and AlbersProjection_true
solid-eureka Oct 1, 2026
939933e
Fix log paths for --benchmark-dir with other folder names
solid-eureka Oct 14, 2026
4328048
Add swat-benchmarks: pruning benefit families and SA soundness pairs
solid-eureka Oct 14, 2026
8bf59a1
swat-benchmarks: add narrowing tasks for SA and executor false SAFEs
solid-eureka Oct 14, 2026
fcb2aa6
swat-benchmarks: add real-tools harnesses (getopt, opencsv) and repor…
solid-eureka Oct 14, 2026
92fc813
swat-benchmarks: add README and results write-up
solid-eureka Oct 14, 2026
289f411
Mention swat-benchmarks in CLAUDE.md
solid-eureka Oct 14, 2026
563bd52
RESULTS.md: count family and soundness false SAFEs separately
solid-eureka Oct 15, 2026
38ac0b7
CLAUDE.md: note that asserts are only the first pruning target
solid-eureka Oct 15, 2026
e343ec1
build: make SV-COMP archive run on Ubuntu 26.04 (SV-COMP 2027)
nils-loose Oct 15, 2026
737f96e
Emit YAML violation witnesses (format 2.3) for SV-COMP 2027
nils-loose Oct 15, 2026
bb8ff31
CLAUDE.md: note the deferred trace-event and id-pairing redesign
solid-eureka Oct 15, 2026
90fd881
Send the trace before System.exit, Runtime.exit and Runtime.halt in S…
solid-eureka Oct 15, 2026
b67695d
Track non-capturing lambda bodies; record context loss when instrumen…
solid-eureka Oct 15, 2026
45c2cd6
Keep symbolic arguments of Method.invoke: unbox them, handle static t…
solid-eureka Oct 15, 2026
d612f78
Record precision loss for symbolic indices into object or untracked a…
solid-eureka Oct 15, 2026
b6573fb
Pass solved inputs back by name, ignoring symbolic values that are no…
solid-eureka Oct 15, 2026
16303f1
Keep String inputs within Java chars and pass them back exactly
solid-eureka Oct 15, 2026
afbd1db
Do not count constraints over String inputs as precision loss
solid-eureka Oct 15, 2026
3b2b979
Follow the NullPointerException of a field access on null instead of …
solid-eureka Oct 15, 2026
f1ee845
Close static initializers left by an exception before the invoke belo…
solid-eureka Oct 15, 2026
b14fdaf
Merge remote-tracking branch 'origin/feat/yaml-witnesses' into feat/w…
nils-loose Oct 15, 2026
7430bef
Ship witness data in the trace instead of stdout markers
nils-loose Oct 15, 2026
feaa359
Write SV-COMP violation witnesses from the trace via witnesscreator
nils-loose Oct 15, 2026
39188f8
Package witnesscreator instead of the WitnessCreator jar
nils-loose Oct 15, 2026
be5ddca
Validate the explorer-written witnesses in the local harness
nils-loose Oct 15, 2026
f18d36f
Record the calling method and send the trace on System.exit
nils-loose Oct 15, 2026
1a05ac4
Model StringBuilder.setLength for concrete lengths
solid-eureka Oct 16, 2026
6bbd2b8
swat-benchmarks: add StringBuilder.setLength reproducer
solid-eureka Oct 16, 2026
1736b17
CLAUDE.md: note String input escaping and the new soundness flags
solid-eureka Oct 16, 2026
5c0fdec
Give every String input its own object, so equal inputs keep separate…
solid-eureka Oct 16, 2026
34cd826
Model String.indexOf(String, int) with Java's clamping of fromIndex
solid-eureka Oct 16, 2026
18b0af7
Report UNKNOWN instead of SAFE after a solution did not reach its branch
solid-eureka Oct 16, 2026
6357110
swat-benchmarks: add reproducers for equal String inputs and indexOf …
solid-eureka Oct 16, 2026
fc8e88e
Find the target of a divergence check by its position, not by its (re…
solid-eureka Oct 16, 2026
71dc9cb
RESULTS.md: add the fixes of 2026-10-15/16 and the runs after them
solid-eureka Oct 16, 2026
9ce3d15
SA graph: model exceptions of unknown type (pseudo types caught by an…
solid-eureka Oct 16, 2026
552bcc0
Stop trusting the SA graph after an exception it does not model
solid-eureka Oct 16, 2026
86c0da2
Close a static initializer left by an exception once the frame below …
solid-eureka Oct 16, 2026
f0ccb96
swat-benchmarks: add S2 reproducers (callee-decided NPE, Error from a…
solid-eureka Oct 16, 2026
fce1bec
Document the S2 fix (unmodelled exceptions) in CLAUDE.md and RESULTS.md
solid-eureka Oct 16, 2026
1e6cdea
swat-benchmarks: add exception-dispatch family (SA precision after un…
solid-eureka Oct 16, 2026
6fb7464
Executor: record HANDLER_ENTRY events
solid-eureka Oct 16, 2026
50ce3ff
SA walk: resume at the handler after an unmodelled exception
solid-eureka Oct 16, 2026
7f6aa4c
sa-soundness: handler resumption tasks
solid-eureka Oct 16, 2026
b3a08e7
Docs: handler resumption results
solid-eureka Oct 16, 2026
1568fec
Executor: report branch keys and stack changes in the trace
solid-eureka Oct 17, 2026
fc817ee
SA walk: detect desyncs by key and resync after losing the graph
solid-eureka Oct 17, 2026
66a5d02
Docs: branch keys, desync detection and resync
solid-eureka Oct 17, 2026
8f5505e
Remove handler resumption (covered by resync)
solid-eureka Oct 17, 2026
aa20dab
Mask library callbacks in the SA walk
solid-eureka Oct 17, 2026
8dab346
sa-soundness: library callback tasks; docs
solid-eureka Oct 17, 2026
d8289a7
sa-soundness: library-callback-assert (known false SAFE with SA)
solid-eureka Oct 17, 2026
6ced24e
Flag to turn off callback targets (--sa-no-callback-targets)
solid-eureka Oct 17, 2026
f6197d3
Key the solver's constraint cache by tree node, not iid
solid-eureka Oct 17, 2026
9046cd0
sa-soundness: exec-loop-iid-wrap
solid-eureka Oct 17, 2026
69c6b83
Keep Z3's jar off the extractor's classpath
solid-eureka Oct 17, 2026
98eb95d
SA walk: call sites with several callees (union in summaries, resync …
solid-eureka Oct 17, 2026
65aab6e
Docs: callback targets, multi-target calls, solver cache fix
solid-eureka Oct 17, 2026
604ba0a
Remove dead code left from the SA integration
solid-eureka Oct 17, 2026
8f0501b
Remove generated timing plot, ignore it
solid-eureka Oct 17, 2026
2f8e874
Merge remote-tracking branch 'origin/feat/witness-via-trace' into svc…
nils-loose Oct 18, 2026
e65dbe2
Merge #65 (static pre-analysis) into the integration branch
nils-loose Oct 18, 2026
f948cb0
Static pre-analysis: prune only under valid-assert and within main's …
nils-loose Oct 18, 2026
6eb7bff
SA walk: do not prune at a branch whose pairing could not be checked
nils-loose Oct 18, 2026
aa8a0ef
Tests for the pre-analysis guards and unchecked pairings
nils-loose Oct 18, 2026
45addc3
Encode NaN and signed zeros in FCMPG/FCMPL
nils-loose Oct 18, 2026
896cab9
Support Verifier.nondetObject in the SV-COMP instrumentation
nils-loose Oct 18, 2026
8f78f91
Re-solve a branch whose solution's run does not reach it
nils-loose Oct 18, 2026
42ac10b
Release the Database lock on exceptions and record traces that cannot…
nils-loose Oct 18, 2026
f83326f
End a failed or incomplete SV-COMP run with UNKNOWN
nils-loose Oct 18, 2026
58c15ae
Extract constraint variables without recursion, each subterm once
nils-loose Oct 18, 2026
373384d
Build and walk the execution tree iteratively; keep UNMODELLED_EXCEPT…
nils-loose Oct 18, 2026
e9ae9b0
Make the class name check descriptor-aware
nils-loose Oct 18, 2026
508db53
Add a static check for uncaught RuntimeExceptions and AssertionErrors
nils-loose Oct 18, 2026
2273466
Answer SAFE when the property pre-check proves the property
nils-loose Oct 18, 2026
c41571f
Test the property pre-check and the verdict it gives
nils-loose Oct 18, 2026
3445d64
Check only the static initializers that may run
nils-loose Oct 18, 2026
eaeb2d9
Continue the running symbolic execution in nested endpoints
nils-loose Oct 18, 2026
b09b432
Start the symbolic execution in the entry class's static initializer
nils-loose Oct 18, 2026
d0d7357
Close soundness gaps in the exception-freedom check
nils-loose Oct 18, 2026
de4930b
Report an assertion failure where its AssertionError is thrown
nils-loose Oct 18, 2026
cfdc451
Branch on the element a symbolic index selects in an object array
nils-loose Oct 18, 2026
cbd98d0
Hold the SA walk in place over choice branches
nils-loose Oct 18, 2026
9f0306e
Test the object-array index search in a forked agent
nils-loose Oct 18, 2026
f55b477
Decide precision loss by symbol kind instead of by name
nils-loose Oct 18, 2026
db4cd1e
Declare the approximate UF models and record their precision loss
nils-loose Oct 18, 2026
edf7764
Model Integer/Long bit operations and radix-2^k string conversions
nils-loose Oct 18, 2026
31aab84
Fix Short.compareUnsigned model to return the difference
nils-loose Oct 18, 2026
cf03553
Model Double.doubleToLongBits/doubleToRawLongBits, canonicalise NaN bits
nils-loose Oct 18, 2026
4ce61c0
Add spec comparing Integer/Long/Short/Byte/Double/Float models with t…
nils-loose Oct 18, 2026
506c20b
Return a concrete result from Objects.equals with a null operand
nils-loose Oct 18, 2026
0152059
Reproduce Java reference identity in the IF_ACMP rewrite
nils-loose Oct 18, 2026
6d51129
Downgrade SAFE on a reference semantic change
nils-loose Oct 18, 2026
1675424
Treat calls that a library default method may serve as unknown
nils-loose Oct 18, 2026
9358459
Model Math.round, max/min, signum, floorDiv and floorMod exactly
nils-loose Oct 18, 2026
adebf40
Model transcendental Math calls as per-call uninterpreted functions
nils-loose Oct 18, 2026
7141297
Slice UF definitions per query and bound queries over Math models
nils-loose Oct 18, 2026
ae1b9e5
Handle a StackOverflowError in the target as the plain JVM would
nils-loose Oct 18, 2026
db097ce
Do not report a violation of an execution that overflowed the stack
nils-loose Oct 18, 2026
22dce63
Build comparison results and Integer-to-bit-vector conversions over b…
nils-loose Oct 18, 2026
cba8042
Skip functions when reading input values from a model
nils-loose Oct 18, 2026
a33984a
Lower the default resource limit for queries over Math models to 2.5e8
nils-loose Oct 18, 2026
a8c403c
Encode bit-op and radix-string models without shared subterms
nils-loose Oct 18, 2026
c2a4c50
Model reference-only calls on JDK containers
nils-loose Oct 18, 2026
0f84f31
Make the String models match Java
nils-loose Oct 18, 2026
186d971
Make the StringBuilder model exact, and record the index checks of St…
nils-loose Oct 18, 2026
ae83736
Do not count the exactly defined String UFs as precision loss
nils-loose Oct 18, 2026
0df4738
Test that the String and StringBuilder models are exact
nils-loose Oct 18, 2026
1bca0a5
Model System.arraycopy with concrete positions and length
nils-loose Oct 18, 2026
5a33932
Test the JDK container and arraycopy models
nils-loose Oct 18, 2026
634d6f7
Solve comparisons over int_to_bv of string lengths and char codes ove…
nils-loose Oct 18, 2026
5d7de94
Extract constraint variables without recursion, each subterm once
nils-loose Oct 18, 2026
ee59502
Add choice branches: executor-added branches that enumerate an operan…
nils-loose Oct 18, 2026
4c79e69
Model Integer/Long toString and toUnsignedString with a radix
nils-loose Oct 18, 2026
3c8ea30
Fix the string of a negative long or short in concatenation
nils-loose Oct 18, 2026
b701046
Convert floats and doubles to their concrete string
nils-loose Oct 18, 2026
f4486e3
Solve program branches before choice branches
nils-loose Oct 18, 2026
942d66d
Remove the unused SVCompHandler
nils-loose Oct 18, 2026
a863ff5
Keep SV-COMP runs within the competition's memory and CPU budget
nils-loose Oct 18, 2026
2b6ba31
Test the number-to-string models against the JDK
nils-loose Oct 18, 2026
0269e0b
Run the executor JVM with the C1 compiler only
nils-loose Oct 18, 2026
a1c072c
Use the same resource budget in the competition package and the harness
nils-loose Oct 18, 2026
ab37625
Do not close the solver context at the end of an SV-COMP execution
nils-loose Oct 18, 2026
f67f39d
Encode the trace with one Z3 solver for all formulas, compact JSON
nils-loose Oct 18, 2026
d1ac405
Create the solver contexts with java-smt's null log manager
nils-loose Oct 18, 2026
2dcd94c
Run the executor JVM with C1 only
nils-loose Oct 18, 2026
e4305de
Select the next branch without copying the execution tree
nils-loose Oct 18, 2026
ac1a353
Keep the nested replace, as precision loss; model the constructor's c…
nils-loose Oct 18, 2026
9cd00a6
Fail the check when the JVM would not load the classpath as modelled
nils-loose Oct 18, 2026
ccd0536
Stop growing ClassDepot's cached hierarchy lists on every allocation
nils-loose Oct 18, 2026
1624541
Look up the reflected field by its name in Field.get
nils-loose Oct 18, 2026
81f8042
Store String[] rows created by ANEWARRAY into multi-dimensional arrays
nils-loose Oct 18, 2026
30be08f
Close constructor invokes left by an exception inside a constructor
nils-loose Oct 18, 2026
519c375
Resync a diverged primitive value with a context loss instead of halting
nils-loose Oct 18, 2026
3ee3cb4
Convert floats and doubles to strings concretely
nils-loose Oct 18, 2026
f6c0a51
Add agent tests for entry-method start, nested mains and constructor …
nils-loose Oct 18, 2026
339a71c
Encode NaN and signed zeros in FCMP and the compare/compareTo models
nils-loose Oct 18, 2026
a5740d7
Recheck only mutable map keys for symbolic state
nils-loose Oct 18, 2026
db0fff1
Merge remote-tracking branch 'origin/fix/exit-hides-assertion' into s…
nils-loose Oct 18, 2026
acd18e3
Merge remote-tracking branch 'origin/fix/sa-property-guard' into svco…
nils-loose Oct 18, 2026
d0addcf
Merge remote-tracking branch 'origin/fix/uf-detection-by-kind' into s…
nils-loose Oct 18, 2026
d7841dc
Merge remote-tracking branch 'origin/feat/property-aware-downgrade' i…
nils-loose Oct 18, 2026
dc34189
Merge remote-tracking branch 'origin/feat/collections-jdk-models' int…
nils-loose Oct 18, 2026
b1db004
Merge feat/symbolic-object-array-index (#69) into svcomp27/all-fixes
nils-loose Oct 18, 2026
08fcd4e
Count each stop of the resource budget once
nils-loose Oct 18, 2026
a5b76de
Merge feat/number-to-string-models (#76, includes #70) into svcomp27/…
nils-loose Oct 18, 2026
98e402a
Report loop-head states with the trace
nils-loose Oct 18, 2026
1a4e046
Leave out branches below a repeated loop-head state
nils-loose Oct 18, 2026
b138c9d
Enable loop-state matching in the SV-COMP configuration
nils-loose Oct 18, 2026
44a5a24
Bound the time a run spends on loop-head states
nils-loose Oct 18, 2026
6ce97bf
Merge fix/explorer-robustness (#72) into svcomp27/all-fixes
nils-loose Oct 18, 2026
92e8fd1
Give the driver robustness tests a property pre-check
nils-loose Oct 18, 2026
67d6dbe
Merge feat/diverged-branch-retry (#74) into svcomp27/all-fixes
nils-loose Oct 18, 2026
f5eeefb
Adapt the divergence and driver tests to the combined driver
nils-loose Oct 18, 2026
cae0290
Merge fix/string-model-soundness (#75) into svcomp27/all-fixes
nils-loose Oct 18, 2026
358e06f
Merge fix/stackoverflow-handling (#78) into svcomp27/all-fixes
nils-loose Oct 18, 2026
f6624c6
Keep a stack overflow of a trace that could not be added
nils-loose Oct 18, 2026
d1f7ad6
Merge fix/ref-equality-semantics (#79) into svcomp27/all-fixes
nils-loose Oct 18, 2026
d757d7f
Test variable extraction on shared and deep constraint terms
nils-loose Oct 19, 2026
929b11a
End the run when a Z3 query outgrows the memory budget
nils-loose Oct 19, 2026
a29e2b5
Merge feat/math-models (#80) into svcomp27/all-fixes
nils-loose Oct 19, 2026
5c2225e
Declare the sampled Math functions as approximate model functions
nils-loose Oct 19, 2026
65fdc4b
Merge perf/solver-encoding (#81) into svcomp27/all-fixes
nils-loose Oct 19, 2026
1f5f3b0
Merge perf/round-overhead (#82) into svcomp27/all-fixes
nils-loose Oct 19, 2026
f262d4d
See a given-up branch's later-reached side on the tree's node
nils-loose Oct 19, 2026
fbea4c1
Model StringBuffer, case mappings, ignore-case comparisons and simple…
nils-loose Oct 19, 2026
80ce0f0
Model parsing numbers from Strings exactly, with NumberFormatExceptio…
nils-loose Oct 19, 2026
8f36a25
Test that the number parsing models are exact
nils-loose Oct 19, 2026
d80f610
Merge feat/parse-number-models (#83, based on #75) into svcomp27/all-…
nils-loose Oct 19, 2026
925ce9e
Count the CPU time of the whole cgroup against the budget
nils-loose Oct 19, 2026
80287c7
Log the per-node trace of the branch selection below DEBUG
nils-loose Oct 19, 2026
3e3d367
Pass the explorer's output through in run_swat.py
nils-loose Oct 19, 2026
ef7c0ac
Model case mappings and ignore-case comparisons for ASCII strings only
nils-loose Oct 19, 2026
d6a6d21
Keep the module loggers' DEBUG/INFO lines off stdout in sv-comp mode
nils-loose Oct 19, 2026
22e3844
Count a symbolic array length as symbolic
nils-loose Oct 19, 2026
ca0f2a5
Stop reporting loop states after a call into untracked code
nils-loose Oct 19, 2026
730db3a
Add loop-state matching soundness tasks
nils-loose Oct 19, 2026
637b685
Report UNKNOWN for an SV-COMP round in which the target sent no trace
nils-loose Oct 19, 2026
008110b
Add an end-to-end test for targets that fail before main
nils-loose Oct 19, 2026
193fc2b
Cover the competition package wrapper in the failed-start test
nils-loose Oct 19, 2026
4977c74
Merge fix/executor-small-bugs (#86) into svcomp27/all-fixes
nils-loose Oct 19, 2026
bf21183
Leave toLowerCase/toUpperCase of symbolic strings unmodelled; pin bef…
nils-loose Oct 19, 2026
0b601b2
Merge fix/resource-budget (#88) into svcomp27/all-fixes
nils-loose Oct 19, 2026
403985d
Give the driver tests the resource budget and the Database reads
nils-loose Oct 19, 2026
0ff4068
Merge fix/failed-start-unknown (#89) into svcomp27/all-fixes
nils-loose Oct 19, 2026
afd150f
Report UNKNOWN for a failed start also when the pre-check proved the …
nils-loose Oct 19, 2026
29b8c03
Test equalsIgnoreCase of two symbolic strings under its branches
nils-loose Oct 19, 2026
c373130
Merge feat/string-models-2 (#90, based on #75) into svcomp27/all-fixes
nils-loose Oct 19, 2026
4b33c36
Mark the number-parsing branches as checks or splits
nils-loose Oct 19, 2026
d1b8fb8
Merge feat/loop-state-matching (#84) into svcomp27/all-fixes
nils-loose Oct 19, 2026
c89050b
Prune only the dominated subtree in the iterative walk; attach loop s…
nils-loose Oct 19, 2026
54a2c21
Update Z3 to 5.3.1 in the executor and the explorer
nils-loose Oct 20, 2026
09c4552
Update ASM, Jackson, logback, SLF4J, Spock and Mockito
nils-loose Oct 20, 2026
0fc33f3
Update Gradle to 8.14.6 and the build plugins
nils-loose Oct 20, 2026
5cdec5c
Update the Python dependencies
nils-loose Oct 20, 2026
57413b5
Update the GitHub Actions used by CI
nils-loose Oct 20, 2026
f2d8115
Keep Z3's previous regex solver in the explorer
nils-loose Oct 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
101 changes: 28 additions & 73 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,51 +6,33 @@ on:
workflow_dispatch:

env:
SVCOMP_VENV_DIR_NAME: .venv_ubuntu_24_04_1__x86_64
WITNESS_CREATOR_VERSION: v0.1.1
WITNESS_CREATOR_SHA256: 8fc8810237c99bf7d709bdb8692142695e407b5681e818fcfe8b45f9c598d814
# Python of the SV-COMP execution environment (SV-COMP 2027: Ubuntu 26.04).
SVCOMP_PYTHON_VERSION: '3.14'
SVCOMP_BASE_IMAGE: docker.io/ubuntu:26.04

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
- name: Set up JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@v6
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4
uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0
- name: Prepare Solver Dependencies
run: ./gradlew copyNativeLibs
- name: Build
run: ./gradlew --no-daemon build -x test
- name: Collect JavaSMT JAR
run: |
java_smt_dir="${HOME}/.gradle/caches/modules-2/files-2.1/org.sosy-lab/java-smt"
if [[ ! -d "$java_smt_dir" ]]; then
echo "JavaSMT Gradle cache directory not found: $java_smt_dir" >&2
exit 1
fi

java_smt_jar="$(find "$java_smt_dir" -type f -name 'java-smt-*.jar' ! -name '*-sources.jar' ! -name '*-javadoc.jar' | sort | tail -n 1)"
if [[ -z "$java_smt_jar" ]]; then
echo "JavaSMT JAR not found in Gradle cache: $java_smt_dir" >&2
exit 1
fi

mkdir -p build/svcomp-runtime
cp "$java_smt_jar" build/svcomp-runtime/java-smt-latest.jar
- name: Upload JARs
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: release-jars-${{ github.sha }}
path: |
symbolic-executor/lib/symbolic-executor.jar
build/svcomp-runtime/java-smt-latest.jar
path: symbolic-executor/lib/symbolic-executor.jar
if-no-files-found: error
retention-days: 1

Expand All @@ -74,34 +56,12 @@ jobs:
prerelease: ${{ steps.meta.outputs.prerelease }}
artifact-name: ${{ steps.meta.outputs.artifact-name }}
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
- name: Download JARs
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: release-jars-${{ github.sha }}
path: ${{ runner.temp }}/release-jars
- name: Install JavaSMT packaging artifact
run: |
mkdir -p libs/java-library-path
cp "${RUNNER_TEMP}/release-jars/build/svcomp-runtime/java-smt-latest.jar" \
libs/java-library-path/java-smt-latest.jar
- name: Download WitnessCreator runtime
run: |
version="${WITNESS_CREATOR_VERSION}"
zip_name="witness-creator-${version#v}.zip"
zip_path="${RUNNER_TEMP}/${zip_name}"
runtime_dir="${RUNNER_TEMP}/witness-creator-runtime"

curl --fail --location --retry 3 \
--output "${zip_path}" \
"https://github.com/SWAT-project/WitnessCreator/releases/download/${version}/${zip_name}"
echo "${WITNESS_CREATOR_SHA256} ${zip_path}" | sha256sum --check -

mkdir -p "${runtime_dir}"
unzip -q "${zip_path}" -d "${runtime_dir}"
test -f "${runtime_dir}/WitnessCreator/build/libs/WitnessCreator.jar"
test -f "${runtime_dir}/WitnessCreator/witnesses/default_violation.st"
test -f "${runtime_dir}/WitnessCreator/witnesses/witness.st"
- name: Determine release channel
id: meta
run: |
Expand Down Expand Up @@ -148,26 +108,21 @@ jobs:
} >> "${GITHUB_OUTPUT}"
- name: Build SV-COMP Python runtime
env:
VENV_DIR: ${{ runner.temp }}/svcomp-runtime/${{ env.SVCOMP_VENV_DIR_NAME }}
run: |
mkdir -p "$(dirname "${VENV_DIR}")"
/usr/bin/python3 -m venv --copies "${VENV_DIR}"
"${VENV_DIR}/bin/python3" -m pip install --no-deps -r scripts/svcomp-package/requirements.txt
"${VENV_DIR}/bin/python3" -m pip check
"${VENV_DIR}/bin/python3" -m pip freeze --all > "${VENV_DIR}/requirements.freeze.txt"
"${VENV_DIR}/bin/python3" -c "import fastapi, pydantic, z3"
SWAT_SVCOMP_PYTHON_VERSION: ${{ env.SVCOMP_PYTHON_VERSION }}
run: scripts/build-svcomp-python-runtime.sh "${RUNNER_TEMP}/svcomp-python"
- name: Pack SV-COMP ZIP
env:
SWAT_SVCOMP_VERSION: ${{ steps.meta.outputs.version }}
SWAT_SVCOMP_ARTIFACT_DIR: ${{ runner.temp }}/release-jars
SWAT_SVCOMP_RUNTIME_DIR: ${{ runner.temp }}/svcomp-runtime
SWAT_SVCOMP_WITNESS_CREATOR_DIR: ${{ runner.temp }}/witness-creator-runtime/WitnessCreator
SWAT_SVCOMP_PYTHON_DIR: ${{ runner.temp }}/svcomp-python
SWAT_SVCOMP_COMMIT: ${{ github.sha }}
SWAT_SVCOMP_REF: ${{ github.ref_name }}
SWAT_SVCOMP_CHANNEL: ${{ steps.meta.outputs.channel }}
run: scripts/package-svcomp.sh
- name: Check SV-COMP ZIP in competition base image
run: scripts/check-svcomp-package.sh "build/distributions/${{ steps.meta.outputs.zip-name }}" "${SVCOMP_BASE_IMAGE}"
- name: Upload SV-COMP ZIP artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: ${{ steps.meta.outputs.artifact-name }}
path: build/distributions/${{ steps.meta.outputs.zip-name }}
Expand All @@ -186,7 +141,7 @@ jobs:
contents: write
steps:
- name: Download SV-COMP ZIP artifact
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: ${{ needs.package.outputs.artifact-name }}
path: ${{ runner.temp }}/svcomp-package
Expand Down Expand Up @@ -234,21 +189,21 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
- name: Set up JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@v6
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4
uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0
- name: Copy Z3
run: ./gradlew copyNativeLibs
- name: Test
run: ./gradlew test
- name: Upload test reports
if: failure()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: test-reports
path: symbolic-executor/build/reports/tests
Expand All @@ -260,18 +215,18 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
- name: Set up JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@v6
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4
uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0
- name: Generate Javadoc
run: ./gradlew :symbolic-executor:javadoc
- name: Upload Javadoc
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: javadoc
path: symbolic-executor/build/docs/javadoc
Expand All @@ -282,11 +237,11 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v7
- name: Set up JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@v6
with:
java-version: '17'
distribution: 'temurin'
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4
uses: gradle/actions/dependency-submission@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,18 @@ libs/jacoco/report
targets/applications/openhospital/oh_build/restler_working_dir/Compile
targets/applications/openhospital/oh_build/restler_working_dir/RestlerResults
targets/sv-comp/sv-benchmarks/
targets/sv-comp/sv-benchmarks-*/
targets/sv-comp/wit4java/
**/__pycache__
**/.venv/*
/.vscode/
**/smt_files/
**/witness/
# ... but not the witness packages of the executor sources
!symbolic-executor/src/**/witness/
**/sv-comp/results/
**/analysis/
!targets/sv-comp/scripts/lib/analysis
libs/cfg-extractor/cfg-extractor-1.0-SNAPSHOT.jar
libs/cfg-extractor/cfg-extractor-1.0-SNAPSHOT.jar
# Default output of targets/sv-comp/scripts/plot_timing_comparison.py
timing_comparison.png
138 changes: 138 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# SWAT

Dynamic symbolic execution for Java:

- `symbolic-executor/` is the Java agent that instruments bytecode and records execution traces.
- `symbolic-explorer/` is the Python driver that builds the execution tree, picks branches to
flip and calls the solver.
- `targets/sv-comp/` holds the SV-COMP harness and benchmarks.

## Static pre-analysis (SA)

The explorer can prune its search with a control-flow graph from the extractor in
`../cfg-extraction`. That graph is loaded by `symbolic-explorer/data/StaticAnalysisGraph/SAGraph.py`
and used in `strategy/DFS.py`.

- **Lockstep walk:** `dfs` walks the execution tree and the SA graph together, pairing branch for
branch **by position**. If the two disagree on how many branches a path has, pruning uses the
wrong nodes and can produce false SAFE verdicts. Any change to what the executor reports as a
branch, including the transformers under `symbolic-executor/.../instrument/`, needs a matching
change in the extractor.
- **Keys check the walk:** every trace branch carries a key (`owner.name(desc)|line|kind|ordinal`,
`instrument/BranchKeys.java`, named in `InstructionMethodAdapter.nameInstruction`) and the frame
stack change since the previous branch (`ShadowContext.takeStackDelta`). `dfs` compares them with
the graph node's key and its own call stack (`SAGraph.check_branch`): a mismatch logs
`[DFS] SA desync`, stops the walk on that path and records `sa_desync`, which turns SAFE into
UNKNOWN. When the walk has no node, `SAGraph.resync` finds the next branch by key, with the call
stack rebuilt from the trace. The extractor computes the same keys; change both together.
- **Concrete branches count:** they are in the tree too. Filtering to symbolic branches happens
after `dfs`.
- **Walker giving up is safe:** when `walk_till_branch` returns `None`, the walker has no
information, and `dfs` treats everything as interesting. That fallback is always safe.
- **Call sites with several callees** (exact dispatch to known overrides): `walk_till_branch`
stops there, and the walk resyncs inside whichever callee ran; summaries take the union.
- **Library callbacks that may reach an assert** make the extractor count every library call as
an assertion point; `--sa-no-callback-targets` (and `svcomp test run --sa-no-callback-targets`)
turns that off, which is unsound. The extractor gets the target's classpath without Z3's jar
(`StaticPreAnalysis._is_swat_library`): its classes would count as application code.
- **`<clinit>` and callbacks are masked:** static initializers are not in the graph, and neither is
application code that library code calls back (the executor flags those branches `callback`,
see `ShadowContext.inCallback`), so the walk is frozen inside them.
- **Asserts are only the first target:** pruning aims at assertion points for now because they
are easy to test (SV-COMP's valid-assert). Later targets include shell calls, SQL statement
building and uncaught exceptions, so prefer changes that work for any kind of target point.
- **Exceptions the graph does not model** (null dereferences, casts, library calls, Errors): the
extractor gives them pseudo types (`?Exception`, `?Error`) whose escapes SAGraph treats as
caught by any handler listed for them (`unknown_handlers`), so paths into such handlers stay
interesting. When one actually happens, the executor records an `UNMODELLED_EXCEPTION` special
event and `dfs` stops trusting the graph until it finds it again at a later branch by key
(resync, see below).
- **SA runs before exploring by default:** in sv-comp mode exploration waits for
`svcomp/StaticPreAnalysis.py`, so the graph is used from round 0 and runs are deterministic.
`--parallel-sa` instead runs the extractor in a thread while exploration starts unpruned;
`SVCompDriver.adopt_sa_graph` switches to the graph once it is loaded, and it is cancelled
(extractor killed) if exploration finishes first. That hides SA bugs whenever the graph loads
too late, and makes results depend on load. In parallel runs the `static_pre_analysis` timing
stage is 0 and its duration is `static_pre_analysis_wall`; `run_info.json` in the run dir records
the SA mode.

Tests for the walk, runnable without a SWAT run:

```bash
cd symbolic-explorer && python3 -m unittest tests.test_sa_walk -v
python3 tests/check_marking_on_graphs.py <graph.json>... # checks marking against an explicit search
../targets/sv-comp/scripts/.venv/bin/python3 -m unittest tests.test_divergence -v # needs the venv
```

`dfs` only descends into real `data.BinaryExecutionTree.Node` instances. In tests, build them with
`Node.__new__(Node)` and set the fields directly. `pytest` is not installed; use `unittest`.

## Decoding executor iids

The branch ids in the explorer log, e.g. `[DFS] @<iid>/<sa node>`, are packed as
`[loop count:6][switch case:4][cid:19][mid:11][inst:24]`. See `GlobalStateForInstrumentation`.

- `cid` is the class index, in load order.
- `mid` is the method index, in declaration order (as `javap -p` lists methods).

Decoding the iids tells you which method each event really came from. That is the quickest way to
spot a walk that has fallen out of step with the execution.

## SV-COMP runs

```bash
cd targets/sv-comp && ./scripts/svcomp test run --mode parallel --no-witness --categories valid-assert.prp
./scripts/svcomp test run --help # --suite, --limit-nr-tests, --no-sa, --parallel-sa, --sa-rank-distance, --solver-rlimit, --testcase-timeout-s ...
```

- **Duration:** a full valid-assert run takes about 40 min with the default 900 s timeout, and
much longer with `--testcase-timeout-s 3600`. Only compare runs made with the same timeout.
- **Resource budget:** as in SV-COMP, the explorer and all executor JVMs share one memory and CPU
budget (`--memory-limit` MB, default 15000; `--cpu-limit` s, default 900; the harness passes
`--testcase-timeout-s` as the CPU limit). The executor heap is derived from the memory limit (a
lower cgroup limit wins). Close to a limit the explorer kills the executor run or interrupts the
Z3 query in progress; 20 s before the CPU limit it ends with UNKNOWN. Both rule out SAFE, see
`symbolic-explorer/svcomp/ResourceBudget.py` and `resources` in `stats.json`.
- **Output:** results go to `targets/sv-comp/runs/run_<timestamp>/`. Per-task results are in
`results/results_<prp>_*.json`, and per-task logs (`explorer.log`,
`Main_main_interprocedural.json`, `stats.json`) are in `logs/<suite>/<task>_<prp>/`.
- **One run at a time:** runs use this working tree live. Every task re-imports
`symbolic-explorer/` and uses `../cfg-extraction/build/libs/`. Ports are pre-assigned upward
from 9000 when a run starts. So don't start a run while another still has live tasks (check
`ps --ppid <svcomp.py pid>`), and remember that editing either repo affects a run in progress.
- **Solver limits:** `--solver-rlimit N` gives each branch's first query N Z3 resource units
(deterministic, unlike a timeout; slow queries run at about 2.5M units/s, so 25000000 is about
10 s). A branch that runs out is retried later with 5x the limit, after the cheaper queries; a
lone retry runs unlimited. Off by default. Each query's time and rlimit use are in the
`[SOLVER]` debug lines of `explorer.log`.
- **Benchmarks:** `targets/sv-comp/sv-benchmarks/` is a sparse checkout of `java/` from
SWAT-project/SV-Benchmarks, which mirrors upstream sv-benchmarks with precompiled `.class` files;
`.last_sv_commit` names the upstream commit. Older suites are kept next to it as
`sv-benchmarks-<date>/` (currently `sv-benchmarks-2025-11-03`, which all runs before the switch on 2026-09-30
used); select one with `--benchmark-dir`, and only compare scores of runs on the same
suite. To update: move the current suite aside, then `./scripts/svcomp setup checkout-benchmarks`
(`--source <local clone>` if GitHub is not reachable over SSH).
- **SA benchmarks:** `targets/sv-comp/swat-benchmarks/` holds generated tasks that measure SA
pruning, and `sa-soundness`, SAFE/VIOLATION pairs where pruning can go wrong (run with
`--benchmark-dir swat-benchmarks --suite sa-soundness`). See its README and RESULTS.md, which
also lists the known SA and executor false SAFEs.
- **Local label fixes:** tasks whose upstream label is wrong are fixed in the suite checkout
itself, as commits there (`git -C targets/sv-comp/sv-benchmarks log`) with a comment in the
task's `.yml`. A fresh checkout drops them, so re-apply any that upstream has not fixed yet:
- `argv-tasks/ReverseInterpolator_true`: valid-assert is false (float rounding, e.g. input
16.84626f); upstream MR 1730 is still open.
- `argv-tasks/PieSegment_true`: valid-assert is false (`angle % 360` is negative for negative
angles); upstream MR 1675 is still open.
- `argv-tasks/AlbersProjection_true`: valid-assert is false (the early return for small `Te`
skips the finite check, e.g. qs = 0, Te = 0 returns 0); no upstream MR yet (MR 1703 was
undone by commit b4857700).
- **Verdicts:** false SAFE (`violation -> safe`) is the outcome that matters most, and a pruning
bug causes exactly that. Check any new one before trusting a run.
- **String inputs:** the explorer passes solved Strings as `-Dswat.input...` escaped by
`escape_java_string` (`driver/SVCompDriver.py`), and the executor's `Verifier.nondetString`
undoes it (`unescape`). Change both together. Solved Strings are read from Z3 by code point
(`SolverHandler.encode_value`); `as_string()` output is ambiguous.
- **Soundness flags that downgrade SAFE to UNKNOWN:** symbolic context loss is also recorded when
instrumented code runs untracked ("unknown space", e.g. a callback from library code), and
precision loss when an object array or an untracked array is indexed symbolically (both only
track the concrete element).
Loading