Skip to content

Commit 010e5fe

Browse files
authored
Fix path condition collection (#94)
* Save all path condition vertices in dumpGameState. * Reset id counter. * Fix problem with multiple ids for a single term. * Reset collections. Fix bug with missing vertices in GameState. * Replace Dictionary with HashSet. * Refactor.
1 parent 4e90c51 commit 010e5fe

File tree

3 files changed

+45
-32
lines changed

3 files changed

+45
-32
lines changed

VSharp.Explorer/Explorer.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,8 @@ type private SVMExplorer(explorationOptions: ExplorationOptions, statistics: SVM
498498
(Path.Combine(folderToStoreSerializationResult, string firstFreeEpisodeNumber))
499499
s.internalId
500500

501+
pathConditionVertices.Clear()
502+
resetPathConditionVertexIdCounter ()
501503
firstFreeEpisodeNumber <- firstFreeEpisodeNumber + 1
502504

503505
x.Forward(s)

VSharp.IL/Serializer.fs

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ let calculateStateMetrics interproceduralGraphDistanceFrom (state: IGraphTrackab
175175
let mutable notVisitedBasicBlocksInZone = 0
176176
let mutable notTouchedBasicBlocksInZone = 0
177177
let basicBlocks = HashSet<_>()
178+
178179
currentBasicBlock.OutgoingEdges.Values |> Seq.iter basicBlocks.UnionWith
179180

180181
basicBlocks
@@ -348,41 +349,47 @@ let collectStatesInfoToDump (basicBlocks: ResizeArray<BasicBlock>) =
348349

349350
statesInfoToDump
350351

351-
let getFirstFreePathConditionVertexId =
352+
let getFirstFreePathConditionVertexId, resetPathConditionVertexIdCounter =
352353
let mutable count = 0u<pathConditionVertexId>
353354

354355
fun () ->
355356
let res = count
356357
count <- count + 1u<pathConditionVertexId>
357358
res
359+
, fun () -> count <- 0u<pathConditionVertexId>
358360

359-
let pathConditionVertices = Dictionary<Core.term, PathConditionVertex>()
360-
361-
let collectPathCondition term = // TODO: Support other operations
362-
let termsToVisit =
363-
Stack<Core.term * uint<pathConditionVertexId>> [| (term, getFirstFreePathConditionVertexId ()) |]
361+
let pathConditionVertices = HashSet<Core.term>()
362+
let termsWithId = Dictionary<Core.term, uint<pathConditionVertexId>>()
364363

364+
let collectPathCondition
365+
term
366+
(termsWithId: Dictionary<Core.term, uint<pathConditionVertexId>>)
367+
(processedPathConditionVertices: HashSet<Core.term>)
368+
= // TODO: Support other operations
369+
let termsToVisit = Stack<Core.term> [| term |]
365370
let pathConditionDelta = ResizeArray<PathConditionVertex>()
366371

372+
let getIdForTerm term =
373+
if termsWithId.ContainsKey term then
374+
termsWithId.[term]
375+
else
376+
let newId = getFirstFreePathConditionVertexId ()
377+
termsWithId.Add(term, newId)
378+
newId
379+
380+
let handleChild term (children: ResizeArray<_>) =
381+
children.Add(getIdForTerm term)
382+
termsToVisit.Push term
383+
367384
while termsToVisit.Count > 0 do
368-
let currentTerm, currentTermId = termsToVisit.Pop()
385+
let currentTerm = termsToVisit.Pop()
369386

370387
let markAsVisited (vertexType: pathConditionVertexType) children =
371-
let newVertex = PathConditionVertex(currentTermId, vertexType, children)
372-
pathConditionVertices.Add(currentTerm, newVertex)
388+
let newVertex = PathConditionVertex(getIdForTerm currentTerm, vertexType, children)
389+
processedPathConditionVertices.Add currentTerm |> ignore
373390
pathConditionDelta.Add newVertex
374391

375-
let handleTerm term (children: ResizeArray<_>) =
376-
let termId =
377-
if not <| pathConditionVertices.ContainsKey term then
378-
getFirstFreePathConditionVertexId ()
379-
else
380-
pathConditionVertices.[term].Id
381-
382-
children.Add termId
383-
termsToVisit.Push((term, termId))
384-
385-
if not <| pathConditionVertices.ContainsKey currentTerm then
392+
if not <| processedPathConditionVertices.Contains currentTerm then
386393
match currentTerm.term with
387394
| Nop -> markAsVisited pathConditionVertexType.Nop [||]
388395
| Concrete(_, _) -> markAsVisited pathConditionVertexType.Constant [||]
@@ -391,7 +398,7 @@ let collectPathCondition term = // TODO: Support other operations
391398
let children = ResizeArray<uint<pathConditionVertexId>>()
392399

393400
for t in termList do
394-
handleTerm t children
401+
handleChild t children
395402

396403
let children = children.ToArray()
397404

@@ -443,30 +450,30 @@ let collectPathCondition term = // TODO: Support other operations
443450
let children = ResizeArray<uint<pathConditionVertexId>>()
444451

445452
for _, t in PersistentDict.toSeq fields do
446-
handleTerm t children
453+
handleChild t children
447454

448455
markAsVisited pathConditionVertexType.Struct (children.ToArray())
449456
| HeapRef(_, _) -> markAsVisited pathConditionVertexType.HeapRef [||]
450457
| Ref(_) -> markAsVisited pathConditionVertexType.Ref [||]
451458
| Ptr(_, _, t) ->
452459
let children = ResizeArray<uint<pathConditionVertexId>> [||]
453-
handleTerm t children
460+
handleChild t children
454461
markAsVisited pathConditionVertexType.Ptr (children.ToArray())
455462
| Slice(t, listOfTuples) ->
456463
let children = ResizeArray<uint<pathConditionVertexId>> [||]
457-
handleTerm t children
464+
handleChild t children
458465

459466
for t1, t2, t3, _ in listOfTuples do
460-
handleTerm t1 children
461-
handleTerm t2 children
462-
handleTerm t3 children
467+
handleChild t1 children
468+
handleChild t2 children
469+
handleChild t3 children
463470

464471
markAsVisited pathConditionVertexType.Slice (children.ToArray())
465472
| Ite(_) -> markAsVisited pathConditionVertexType.Ite [||]
466473

467474
pathConditionDelta
468475

469-
let collectGameState (basicBlocks: ResizeArray<BasicBlock>) filterStates =
476+
let collectGameState (basicBlocks: ResizeArray<BasicBlock>) filterStates processedPathConditionVertices termsWithId =
470477

471478
let vertices = ResizeArray<_>()
472479
let allStates = HashSet<_>()
@@ -486,13 +493,13 @@ let collectGameState (basicBlocks: ResizeArray<BasicBlock>) filterStates =
486493
let pathCondition = s.PathCondition |> PC.toSeq
487494

488495
for term in pathCondition do
489-
pathConditionDelta.AddRange(collectPathCondition term)
496+
pathConditionDelta.AddRange(collectPathCondition term termsWithId processedPathConditionVertices)
490497

491498
let pathConditionRoot =
492499
PathConditionVertex(
493500
id = getFirstFreePathConditionVertexId (),
494501
pathConditionVertexType = pathConditionVertexType.PathConditionRoot,
495-
children = [| for p in pathCondition -> pathConditionVertices.[p].Id |]
502+
children = [| for p in pathCondition -> termsWithId.[p] |]
496503
)
497504

498505
pathConditionDelta.Add pathConditionRoot
@@ -556,7 +563,7 @@ let collectGameStateDelta () =
556563
let added = basicBlocks.Add(basicBlock)
557564
()
558565

559-
collectGameState (ResizeArray basicBlocks) false
566+
collectGameState (ResizeArray basicBlocks) false pathConditionVertices termsWithId
560567

561568
let dumpGameState fileForResultWithoutExtension (movedStateId: uint<stateId>) =
562569
let basicBlocks = ResizeArray<_>()
@@ -566,7 +573,9 @@ let dumpGameState fileForResultWithoutExtension (movedStateId: uint<stateId>) =
566573
basicBlock.IsGoal <- method.Key.InCoverageZone
567574
basicBlocks.Add(basicBlock)
568575

569-
let gameState = collectGameState basicBlocks true
576+
let gameState =
577+
collectGameState basicBlocks true (HashSet<Core.term>()) (Dictionary<Core.term, uint<pathConditionVertexId>>())
578+
570579
let statesInfoToDump = collectStatesInfoToDump basicBlocks
571580
let gameStateJson = JsonSerializer.Serialize gameState
572581
let statesInfoJson = JsonSerializer.Serialize statesInfoToDump

VSharp.ML.GameServer.Runner/Main.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ let ws port outputDirectory (webSocket: WebSocket) (context: HttpContext) =
231231
API.Reset()
232232
HashMap.hashMap.Clear()
233233
Serializer.pathConditionVertices.Clear()
234+
Serializer.resetPathConditionVertexIdCounter ()
235+
Serializer.termsWithId.Clear()
234236

235237
do!
236238
sendResponse (

0 commit comments

Comments
 (0)