Skip to content

fix: oscillating net pair suspends only that pair, not the whole pass - #1110

Open
tbontb-iaq wants to merge 3 commits into
tscircuit:mainfrom
tbontb-iaq:fix/oscillating-pair-suspends-only-that-pair
Open

fix: oscillating net pair suspends only that pair, not the whole pass#1110
tbontb-iaq wants to merge 3 commits into
tscircuit:mainfrom
tbontb-iaq:fix/oscillating-pair-suspends-only-that-pair

Conversation

@tbontb-iaq

Copy link
Copy Markdown

Fixes #1102

/attempt #1102

Problem

TraceOverlapShiftSolver._step() treated its A -> B -> A oscillation guard as a reason to stop the entire solve (this.solved = true). The first oscillating net pair aborted the whole pass, leaving every other independent cross-net overlap silently unresolved.

Fix

  • On oscillation, the pair is added to suspendedNetPairKeys and only that pair is suspended.
  • findNextOverlapIssue skips suspended pairs, so independent pairs keep being corrected until no correctable overlap remains.

Verification (minimized repro from the issue, 5 chips / 14 pins)

Before: solver stops at iteration 9 with 2 cross-net pairs still collinearly overlapping (GND/VBUS oscillating + RTS/DTR independent).
After: 1 remains — only the genuinely oscillating GND/VBUS pair, exactly the expected behavior. RTS/DTR is separated.

On the full board-1273 fixture: unresolved cross-net pairs go from 6 down to 1 (the single oscillating pair), solved in 37 iterations; no traces added or dropped. The repro test's iteration-count assertion was updated accordingly and its SVG snapshot regenerated (routing visibly changed only in the regions where the previously-aborted pairs now get corrected).

Full suite: 353 pass / 0 fail (357 tests, 4 skipped).

segmentIntersectsRect declared any segment that is neither exactly
vertical nor exactly horizontal collision-free. Real pin coordinates
are not always exactly on the routing grid (e.g. x = 5.3999378 next to
x = 5.4), so nearly axis-aligned segments sailed through chip bodies
and were accepted by UnroutedTraceRecoverySolver as collision-free.

Non-axis-aligned segments now run a slab (Liang-Barsky) clip against
the rect. Axis-aligned fast paths keep their historical semantics:
a real interior overlap counts, a segment that merely touches an edge
or corner does not (tMax - tMin > eps for the slanted path).

Fixes tscircuit#1099
TraceOverlapShiftSolver treated its A -> B -> A oscillation guard as a
reason to stop the entire solve. The first oscillating net pair aborted
the pass, leaving every other independent cross-net overlap unresolved.

Suspending only the oscillating pair lets the remaining pairs be
corrected. The minimized repro from issue tscircuit#1102 now resolves the
RTS/DTR overlap (2 surviving cross-net overlaps -> 1, the genuinely
oscillating GND/VBUS pair); board-1273 goes from 6 unresolved pairs
down to 1 in 37 iterations (previously 6 pairs after 27).

Fixes tscircuit#1102
@vercel

vercel Bot commented Sep 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
schematic-trace-solver Ready Ready Preview Sep 9, 2026 3:11am UTC

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: a single oscillating net pair aborts TraceOverlapShiftSolver and leaves independent cross-net overlaps unresolved

1 participant