api: /maxflow?trace=true ships the whole trace statelessly (closes #36) - #58
Closed
bgent19 wants to merge 2 commits into
Closed
api: /maxflow?trace=true ships the whole trace statelessly (closes #36)#58bgent19 wants to merge 2 commits into
bgent19 wants to merge 2 commits into
Conversation
Day 2 steps through Edmonds-Karp with the arrow keys, so the entire trace ships as one array in one call and backward stepping is an index decrement. Each entry is a complete snapshot, never a delta, which is what makes that possible -- a server-side cursor would have broken the API's own no-leaked- state promise for no gain. The data layer stops filtering and the CLI starts. Two filters existed purely to tidy CLI output and both damaged a drawing consumer: stripping the synthetic terminals made a route appear to begin mid-graph, and dropping unbounded terms de-aligned lane_residuals from path so a min(...) term could not be anchored to its lane. Both now ship complete -- terminals named __source__/__sink__, unbounded residuals as null -- and cli.cmd_maxflow narrows at print time. The solver also states per-arc flows on every step, zeros included, closing the trap where a saturated lane was indistinguishable from an absent one. Computed server-side rather than as cap - residual in the browser. Adds a step 0: the graph before the first push, so the frontend's uniform "residuals from k-1, path from k" render rule has a before-state for iteration 1 without building residual graphs in JavaScript. tests/golden/ pins the --trace lecture text character for character. The goldens were generated from the CLI before the split existed, so they are evidence the narrowing is exact rather than approximately right.
The display helper sniffed tuple length to accept both (u, v) pairs and (u, v, residual) triples; it is now two named helpers, one per shape. The None-residual guard is redundant today -- only terminal arcs are unbounded, and dropping the synthetic endpoints already drops them -- and is kept because the alternative is a TypeError mid-lecture if that stops being true. _snapshot's bottleneck and total are the same type and adjacent, so transposing them would be a silent wrong number on the projector. Keyword-only.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #36. Based on
classdemos(notmain) because it stacks on #35'sapi.pychanges.GET /maxflowgainstrace: bool = False. When true the whole Edmonds–Karp trace ships as one array — every augmentation, complete enough to draw, with no server-side cursor.What changed
EdmondsKarp._snapshotstates the entire residual graph and every arc's flow each time.__source__/__sink__and retained; unbounded residuals ship asnulland stay in place, solane_residualsis one term per hop and amin(...)term can be anchored to its lane.cli.cmd_maxflownarrows at print time.flowsstates every arc, zeros included, closing the trap where a saturated lane was indistinguishable from an absent one. Server-computed, notcap − residualin JS.MaxFlowResponse/TraceStepOutdocument the shape at/docs.trace=falsekeeps all four existing fields and their values, adding an emptytracearray.Edge identity is deliberately not threaded through the arc generator, per the issue.
Verification
tests/golden/pins the--tracelecture text character for character. The goldens were generated from the CLI before the split existed, so they are evidence the narrowing is exact rather than approximately right — a reviewer independently checked out the pre-change commit and diffed; both datasets came back empty.len(lane_residuals) == max(len(path) - 1, 0)(the spec's formula, guarded for step 0's empty path), terminal retention,null-never-Infinity(parsed withparse_constantso a browser-breakingInfinitycannot slip through), flow coverage of saturated lanes, statelessness, and the/docsschema.test_maxflow_interdiction.pyasserted the old filtered shape and were updated to the new contract, keeping their intent — including the load-bearing edge-order assertions that select which cancellation trace students see.🤖 Generated with Claude Code