Skip to content

Fix path condition collection #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions VSharp.Explorer/Explorer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,8 @@ type private SVMExplorer(explorationOptions: ExplorationOptions, statistics: SVM
(Path.Combine(folderToStoreSerializationResult, string firstFreeEpisodeNumber))
s.internalId

pathConditionVertices.Clear()
resetPathConditionVertexIdCounter ()
firstFreeEpisodeNumber <- firstFreeEpisodeNumber + 1

x.Forward(s)
Expand Down
73 changes: 41 additions & 32 deletions VSharp.IL/Serializer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ let calculateStateMetrics interproceduralGraphDistanceFrom (state: IGraphTrackab
let mutable notVisitedBasicBlocksInZone = 0
let mutable notTouchedBasicBlocksInZone = 0
let basicBlocks = HashSet<_>()

currentBasicBlock.OutgoingEdges.Values |> Seq.iter basicBlocks.UnionWith

basicBlocks
Expand Down Expand Up @@ -348,41 +349,47 @@ let collectStatesInfoToDump (basicBlocks: ResizeArray<BasicBlock>) =

statesInfoToDump

let getFirstFreePathConditionVertexId =
let getFirstFreePathConditionVertexId, resetPathConditionVertexIdCounter =
let mutable count = 0u<pathConditionVertexId>

fun () ->
let res = count
count <- count + 1u<pathConditionVertexId>
res
, fun () -> count <- 0u<pathConditionVertexId>

let pathConditionVertices = Dictionary<Core.term, PathConditionVertex>()

let collectPathCondition term = // TODO: Support other operations
let termsToVisit =
Stack<Core.term * uint<pathConditionVertexId>> [| (term, getFirstFreePathConditionVertexId ()) |]
let pathConditionVertices = HashSet<Core.term>()
let termsWithId = Dictionary<Core.term, uint<pathConditionVertexId>>()

let collectPathCondition
term
(termsWithId: Dictionary<Core.term, uint<pathConditionVertexId>>)
(processedPathConditionVertices: HashSet<Core.term>)
= // TODO: Support other operations
let termsToVisit = Stack<Core.term> [| term |]
let pathConditionDelta = ResizeArray<PathConditionVertex>()

let getIdForTerm term =
if termsWithId.ContainsKey term then
termsWithId.[term]
else
let newId = getFirstFreePathConditionVertexId ()
termsWithId.Add(term, newId)
newId

let handleChild term (children: ResizeArray<_>) =
children.Add(getIdForTerm term)
termsToVisit.Push term

while termsToVisit.Count > 0 do
let currentTerm, currentTermId = termsToVisit.Pop()
let currentTerm = termsToVisit.Pop()

let markAsVisited (vertexType: pathConditionVertexType) children =
let newVertex = PathConditionVertex(currentTermId, vertexType, children)
pathConditionVertices.Add(currentTerm, newVertex)
let newVertex = PathConditionVertex(getIdForTerm currentTerm, vertexType, children)
processedPathConditionVertices.Add currentTerm |> ignore
pathConditionDelta.Add newVertex

let handleTerm term (children: ResizeArray<_>) =
let termId =
if not <| pathConditionVertices.ContainsKey term then
getFirstFreePathConditionVertexId ()
else
pathConditionVertices.[term].Id

children.Add termId
termsToVisit.Push((term, termId))

if not <| pathConditionVertices.ContainsKey currentTerm then
if not <| processedPathConditionVertices.Contains currentTerm then
match currentTerm.term with
| Nop -> markAsVisited pathConditionVertexType.Nop [||]
| Concrete(_, _) -> markAsVisited pathConditionVertexType.Constant [||]
Expand All @@ -391,7 +398,7 @@ let collectPathCondition term = // TODO: Support other operations
let children = ResizeArray<uint<pathConditionVertexId>>()

for t in termList do
handleTerm t children
handleChild t children

let children = children.ToArray()

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

for _, t in PersistentDict.toSeq fields do
handleTerm t children
handleChild t children

markAsVisited pathConditionVertexType.Struct (children.ToArray())
| HeapRef(_, _) -> markAsVisited pathConditionVertexType.HeapRef [||]
| Ref(_) -> markAsVisited pathConditionVertexType.Ref [||]
| Ptr(_, _, t) ->
let children = ResizeArray<uint<pathConditionVertexId>> [||]
handleTerm t children
handleChild t children
markAsVisited pathConditionVertexType.Ptr (children.ToArray())
| Slice(t, listOfTuples) ->
let children = ResizeArray<uint<pathConditionVertexId>> [||]
handleTerm t children
handleChild t children

for t1, t2, t3, _ in listOfTuples do
handleTerm t1 children
handleTerm t2 children
handleTerm t3 children
handleChild t1 children
handleChild t2 children
handleChild t3 children

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

pathConditionDelta

let collectGameState (basicBlocks: ResizeArray<BasicBlock>) filterStates =
let collectGameState (basicBlocks: ResizeArray<BasicBlock>) filterStates processedPathConditionVertices termsWithId =

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

for term in pathCondition do
pathConditionDelta.AddRange(collectPathCondition term)
pathConditionDelta.AddRange(collectPathCondition term termsWithId processedPathConditionVertices)

let pathConditionRoot =
PathConditionVertex(
id = getFirstFreePathConditionVertexId (),
pathConditionVertexType = pathConditionVertexType.PathConditionRoot,
children = [| for p in pathCondition -> pathConditionVertices.[p].Id |]
children = [| for p in pathCondition -> termsWithId.[p] |]
)

pathConditionDelta.Add pathConditionRoot
Expand Down Expand Up @@ -556,7 +563,7 @@ let collectGameStateDelta () =
let added = basicBlocks.Add(basicBlock)
()

collectGameState (ResizeArray basicBlocks) false
collectGameState (ResizeArray basicBlocks) false pathConditionVertices termsWithId

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

let gameState = collectGameState basicBlocks true
let gameState =
collectGameState basicBlocks true (HashSet<Core.term>()) (Dictionary<Core.term, uint<pathConditionVertexId>>())

let statesInfoToDump = collectStatesInfoToDump basicBlocks
let gameStateJson = JsonSerializer.Serialize gameState
let statesInfoJson = JsonSerializer.Serialize statesInfoToDump
Expand Down
2 changes: 2 additions & 0 deletions VSharp.ML.GameServer.Runner/Main.fs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ let ws port outputDirectory (webSocket: WebSocket) (context: HttpContext) =
API.Reset()
HashMap.hashMap.Clear()
Serializer.pathConditionVertices.Clear()
Serializer.resetPathConditionVertexIdCounter ()
Serializer.termsWithId.Clear()

do!
sendResponse (
Expand Down
Loading