@tscircuit/schematic-trace-solver 0.0.31 → 0.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md ADDED
@@ -0,0 +1,8 @@
1
+ - use `bunx tsc --noEmit` to type check
2
+ - use `bun test path/to/test.ts` to run a test
3
+ - use `bun add <package>` to add a package
4
+
5
+ There are two ways the user tests the algorithm:
6
+
7
+ - Running `bun test`
8
+ - Looking at the `*.page.tsx` files in the `site` directory via a browser
package/dist/index.js CHANGED
@@ -607,7 +607,8 @@ var cartesian = (arrays) => arrays.length === 0 ? [[]] : arrays.reduce(
607
607
  );
608
608
  var generateElbowVariants = ({
609
609
  baseElbow,
610
- guidelines
610
+ guidelines,
611
+ maxVariants = 1e4
611
612
  }) => {
612
613
  const elbow = preprocessElbow(baseElbow);
613
614
  assertOrthogonalPolyline(elbow);
@@ -692,6 +693,9 @@ var generateElbowVariants = ({
692
693
  if (!seen.has(key)) {
693
694
  seen.add(key);
694
695
  elbowVariants.push(variant);
696
+ if (elbowVariants.length >= maxVariants) {
697
+ break;
698
+ }
695
699
  }
696
700
  }
697
701
  return { elbowVariants, movableSegments };
@@ -868,7 +872,8 @@ var SchematicTraceSingleLineSolver = class extends BaseSolver {
868
872
  );
869
873
  const { elbowVariants, movableSegments } = generateElbowVariants({
870
874
  baseElbow: this.baseElbow,
871
- guidelines: this.guidelines
875
+ guidelines: this.guidelines,
876
+ maxVariants: 1e3
872
877
  });
873
878
  this.movableSegments = movableSegments;
874
879
  const getPathLength = (pts) => {
@@ -906,6 +911,7 @@ var SchematicTraceSingleLineSolver = class extends BaseSolver {
906
911
  pinIdMap: this.pinIdMap,
907
912
  chipMap: this.chipMap
908
913
  });
914
+ let pathIsValid = true;
909
915
  for (let i = 0; i < nextCandidatePath.length - 1; i++) {
910
916
  const start = nextCandidatePath[i];
911
917
  const end = nextCandidatePath[i + 1];
@@ -913,12 +919,19 @@ var SchematicTraceSingleLineSolver = class extends BaseSolver {
913
919
  const EPS2 = 1e-9;
914
920
  for (const [, rcl] of restrictedCenterLines) {
915
921
  if (rcl.axes.has("x") && typeof rcl.x === "number") {
916
- if ((start.x - rcl.x) * (end.x - rcl.x) < -EPS2) return;
922
+ if ((start.x - rcl.x) * (end.x - rcl.x) < -EPS2) {
923
+ pathIsValid = false;
924
+ break;
925
+ }
917
926
  }
918
927
  if (rcl.axes.has("y") && typeof rcl.y === "number") {
919
- if ((start.y - rcl.y) * (end.y - rcl.y) < -EPS2) return;
928
+ if ((start.y - rcl.y) * (end.y - rcl.y) < -EPS2) {
929
+ pathIsValid = false;
930
+ break;
931
+ }
920
932
  }
921
933
  }
934
+ if (!pathIsValid) break;
922
935
  const isStartPin = this.pins.some(
923
936
  (pin) => Math.abs(pin.x - start.x) < 1e-10 && Math.abs(pin.y - start.y) < 1e-10
924
937
  );
@@ -939,12 +952,16 @@ var SchematicTraceSingleLineSolver = class extends BaseSolver {
939
952
  const onBottom = Math.abs(start.y - bounds.minY) < 1e-9;
940
953
  const onTop = Math.abs(start.y - bounds.maxY) < 1e-9;
941
954
  const entersInterior = onLeft && dx > EPS3 || onRight && dx < -EPS3 || onBottom && dy > EPS3 || onTop && dy < -EPS3;
942
- if (entersInterior) return;
955
+ if (entersInterior) {
956
+ pathIsValid = false;
957
+ break;
958
+ }
943
959
  if (!excludeChipIds.includes(startPin.chipId)) {
944
960
  excludeChipIds.push(startPin.chipId);
945
961
  }
946
962
  }
947
963
  }
964
+ if (!pathIsValid) break;
948
965
  if (isEndPin) {
949
966
  const endPin = this.pins.find(
950
967
  (pin) => Math.abs(pin.x - end.x) < 1e-10 && Math.abs(pin.y - end.y) < 1e-10
@@ -959,21 +976,30 @@ var SchematicTraceSingleLineSolver = class extends BaseSolver {
959
976
  const onBottom = Math.abs(end.y - bounds.minY) < 1e-9;
960
977
  const onTop = Math.abs(end.y - bounds.maxY) < 1e-9;
961
978
  const entersInterior = onLeft && dx > EPS3 || onRight && dx < -EPS3 || onBottom && dy > EPS3 || onTop && dy < -EPS3;
962
- if (entersInterior) return;
979
+ if (entersInterior) {
980
+ pathIsValid = false;
981
+ break;
982
+ }
963
983
  if (!excludeChipIds.includes(endPin.chipId)) {
964
984
  excludeChipIds.push(endPin.chipId);
965
985
  }
966
986
  }
967
987
  }
988
+ if (!pathIsValid) break;
968
989
  const obstacleOps = { excludeChipIds };
969
990
  const intersects = this.chipObstacleSpatialIndex.doesOrthogonalLineIntersectChip(
970
991
  [start, end],
971
992
  obstacleOps
972
993
  );
973
- if (intersects) return;
994
+ if (intersects) {
995
+ pathIsValid = false;
996
+ break;
997
+ }
998
+ }
999
+ if (pathIsValid) {
1000
+ this.solvedTracePath = nextCandidatePath;
1001
+ this.solved = true;
974
1002
  }
975
- this.solvedTracePath = nextCandidatePath;
976
- this.solved = true;
977
1003
  }
978
1004
  visualize() {
979
1005
  const graphics = visualizeInputProblem(this.inputProblem, {
@@ -1095,11 +1121,11 @@ var SchematicTraceLinesSolver = class extends BaseSolver {
1095
1121
  return;
1096
1122
  }
1097
1123
  const connectionPair = this.queuedConnectionPairs.shift();
1098
- this.currentConnectionPair = connectionPair;
1099
1124
  if (!connectionPair) {
1100
1125
  this.solved = true;
1101
1126
  return;
1102
1127
  }
1128
+ this.currentConnectionPair = connectionPair;
1103
1129
  const { pins } = connectionPair;
1104
1130
  this.activeSubSolver = new SchematicTraceSingleLineSolver({
1105
1131
  inputProblem: this.inputProblem,
@@ -101,13 +101,14 @@ export class SchematicTraceLinesSolver extends BaseSolver {
101
101
  }
102
102
 
103
103
  const connectionPair = this.queuedConnectionPairs.shift()
104
- this.currentConnectionPair = connectionPair!
105
104
 
106
105
  if (!connectionPair) {
107
106
  this.solved = true
108
107
  return
109
108
  }
110
109
 
110
+ this.currentConnectionPair = connectionPair
111
+
111
112
  const { pins } = connectionPair
112
113
 
113
114
  this.activeSubSolver = new SchematicTraceSingleLineSolver({
@@ -97,6 +97,7 @@ export class SchematicTraceSingleLineSolver extends BaseSolver {
97
97
  const { elbowVariants, movableSegments } = generateElbowVariants({
98
98
  baseElbow: this.baseElbow,
99
99
  guidelines: this.guidelines,
100
+ maxVariants: 1000,
100
101
  })
101
102
 
102
103
  this.movableSegments = movableSegments
@@ -144,6 +145,9 @@ export class SchematicTraceSingleLineSolver extends BaseSolver {
144
145
  chipMap: this.chipMap,
145
146
  })
146
147
 
148
+ // Check if this candidate path is valid
149
+ let pathIsValid = true
150
+
147
151
  for (let i = 0; i < nextCandidatePath.length - 1; i++) {
148
152
  const start = nextCandidatePath[i]
149
153
  const end = nextCandidatePath[i + 1]
@@ -156,14 +160,22 @@ export class SchematicTraceSingleLineSolver extends BaseSolver {
156
160
  for (const [, rcl] of restrictedCenterLines) {
157
161
  if (rcl.axes.has("x") && typeof rcl.x === "number") {
158
162
  // segment strictly crosses vertical center line
159
- if ((start.x - rcl.x) * (end.x - rcl.x) < -EPS) return
163
+ if ((start.x - rcl.x) * (end.x - rcl.x) < -EPS) {
164
+ pathIsValid = false
165
+ break
166
+ }
160
167
  }
161
168
  if (rcl.axes.has("y") && typeof rcl.y === "number") {
162
169
  // segment strictly crosses horizontal center line
163
- if ((start.y - rcl.y) * (end.y - rcl.y) < -EPS) return
170
+ if ((start.y - rcl.y) * (end.y - rcl.y) < -EPS) {
171
+ pathIsValid = false
172
+ break
173
+ }
164
174
  }
165
175
  }
166
176
 
177
+ if (!pathIsValid) break
178
+
167
179
  // Always exclude chips that contain the start or end points of this segment
168
180
  // if those points are actually pin locations
169
181
  const isStartPin = this.pins.some(
@@ -197,13 +209,18 @@ export class SchematicTraceSingleLineSolver extends BaseSolver {
197
209
  (onRight && dx < -EPS) ||
198
210
  (onBottom && dy > EPS) ||
199
211
  (onTop && dy < -EPS)
200
- if (entersInterior) return
212
+ if (entersInterior) {
213
+ pathIsValid = false
214
+ break
215
+ }
201
216
  if (!excludeChipIds.includes(startPin.chipId)) {
202
217
  excludeChipIds.push(startPin.chipId)
203
218
  }
204
219
  }
205
220
  }
206
221
 
222
+ if (!pathIsValid) break
223
+
207
224
  if (isEndPin) {
208
225
  const endPin = this.pins.find(
209
226
  (pin) =>
@@ -224,24 +241,37 @@ export class SchematicTraceSingleLineSolver extends BaseSolver {
224
241
  (onRight && dx < -EPS) ||
225
242
  (onBottom && dy > EPS) ||
226
243
  (onTop && dy < -EPS)
227
- if (entersInterior) return
244
+ if (entersInterior) {
245
+ pathIsValid = false
246
+ break
247
+ }
228
248
  if (!excludeChipIds.includes(endPin.chipId)) {
229
249
  excludeChipIds.push(endPin.chipId)
230
250
  }
231
251
  }
232
252
  }
233
253
 
254
+ if (!pathIsValid) break
255
+
234
256
  const obstacleOps = { excludeChipIds }
235
257
  const intersects =
236
258
  this.chipObstacleSpatialIndex.doesOrthogonalLineIntersectChip(
237
259
  [start, end],
238
260
  obstacleOps,
239
261
  )
240
- if (intersects) return
262
+ if (intersects) {
263
+ pathIsValid = false
264
+ break
265
+ }
241
266
  }
242
267
 
243
- this.solvedTracePath = nextCandidatePath
244
- this.solved = true
268
+ // If this path is valid, use it as the solution
269
+ if (pathIsValid) {
270
+ this.solvedTracePath = nextCandidatePath
271
+ this.solved = true
272
+ }
273
+ // If this path is invalid, continue to next step to try the next candidate
274
+ // The next _step() call will try the next candidate path
245
275
  }
246
276
 
247
277
  override visualize(): GraphicsObject {
@@ -260,9 +260,11 @@ const cartesian = <T>(arrays: T[][]): T[][] =>
260
260
  export const generateElbowVariants = ({
261
261
  baseElbow,
262
262
  guidelines,
263
+ maxVariants = 10000,
263
264
  }: {
264
265
  baseElbow: Point[]
265
266
  guidelines: Guideline[]
267
+ maxVariants?: number
266
268
  }): {
267
269
  elbowVariants: Array<Point[]>
268
270
  movableSegments: Array<MovableSegment>
@@ -395,6 +397,11 @@ export const generateElbowVariants = ({
395
397
  if (!seen.has(key)) {
396
398
  seen.add(key)
397
399
  elbowVariants.push(variant)
400
+
401
+ // Stop if we've hit the maximum number of variants
402
+ if (elbowVariants.length >= maxVariants) {
403
+ break
404
+ }
398
405
  }
399
406
  }
400
407
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/schematic-trace-solver",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.31",
4
+ "version": "0.0.32",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "start": "cosmos",
@@ -0,0 +1,486 @@
1
+ import { PipelineDebugger } from "site/components/PipelineDebugger"
2
+ import type { InputProblem } from "lib/types/InputProblem"
3
+
4
+ export const inputProblem: InputProblem = {
5
+ chips: [
6
+ {
7
+ chipId: "schematic_component_0",
8
+ center: {
9
+ x: 0,
10
+ y: 0,
11
+ },
12
+ width: 2.3,
13
+ height: 1.4,
14
+ pins: [
15
+ {
16
+ pinId: "J1.1",
17
+ x: 1.15,
18
+ y: 0.5,
19
+ },
20
+ {
21
+ pinId: "J1.2",
22
+ x: 1.15,
23
+ y: 0.30000000000000004,
24
+ },
25
+ {
26
+ pinId: "J1.3",
27
+ x: 1.15,
28
+ y: 0.10000000000000009,
29
+ },
30
+ {
31
+ pinId: "J1.4",
32
+ x: 1.15,
33
+ y: -0.09999999999999998,
34
+ },
35
+ {
36
+ pinId: "J1.5",
37
+ x: 1.15,
38
+ y: -0.3,
39
+ },
40
+ {
41
+ pinId: "J1.6",
42
+ x: 1.15,
43
+ y: -0.5,
44
+ },
45
+ ],
46
+ },
47
+ {
48
+ chipId: "schematic_component_1",
49
+ center: {
50
+ x: 1.56,
51
+ y: 4.308333333333334,
52
+ },
53
+ width: 1,
54
+ height: 0.45,
55
+ pins: [
56
+ {
57
+ pinId: "SW1.1",
58
+ x: 1.06,
59
+ y: 4.258333333333334,
60
+ },
61
+ {
62
+ pinId: "SW1.2",
63
+ x: 2.06,
64
+ y: 4.258333333333334,
65
+ },
66
+ ],
67
+ },
68
+ {
69
+ chipId: "schematic_component_2",
70
+ center: {
71
+ x: 0.3599999999999999,
72
+ y: 4.308333333333334,
73
+ },
74
+ width: 1.04,
75
+ height: 0.54,
76
+ pins: [
77
+ {
78
+ pinId: "D1.1",
79
+ x: -0.16000000000000014,
80
+ y: 4.308333333333334,
81
+ },
82
+ {
83
+ pinId: "D1.2",
84
+ x: 0.8799999999999999,
85
+ y: 4.308333333333334,
86
+ },
87
+ ],
88
+ },
89
+ {
90
+ chipId: "schematic_component_3",
91
+ center: {
92
+ x: 5.06,
93
+ y: 0.3583333333333334,
94
+ },
95
+ width: 1,
96
+ height: 0.45,
97
+ pins: [
98
+ {
99
+ pinId: "SW2.1",
100
+ x: 4.56,
101
+ y: 0.30833333333333357,
102
+ },
103
+ {
104
+ pinId: "SW2.2",
105
+ x: 5.56,
106
+ y: 0.30833333333333357,
107
+ },
108
+ ],
109
+ },
110
+ {
111
+ chipId: "schematic_component_4",
112
+ center: {
113
+ x: 3.8599999999999994,
114
+ y: 0.3583333333333334,
115
+ },
116
+ width: 1.040000000000001,
117
+ height: 0.54,
118
+ pins: [
119
+ {
120
+ pinId: "D2.1",
121
+ x: 3.339999999999999,
122
+ y: 0.3583333333333334,
123
+ },
124
+ {
125
+ pinId: "D2.2",
126
+ x: 4.38,
127
+ y: 0.3583333333333334,
128
+ },
129
+ ],
130
+ },
131
+ {
132
+ chipId: "schematic_component_5",
133
+ center: {
134
+ x: 3.163333333333334,
135
+ y: 10.185,
136
+ },
137
+ width: 1,
138
+ height: 0.45,
139
+ pins: [
140
+ {
141
+ pinId: "SW3.1",
142
+ x: 2.663333333333334,
143
+ y: 10.135,
144
+ },
145
+ {
146
+ pinId: "SW3.2",
147
+ x: 3.663333333333334,
148
+ y: 10.135,
149
+ },
150
+ ],
151
+ },
152
+ {
153
+ chipId: "schematic_component_6",
154
+ center: {
155
+ x: 1.9633333333333338,
156
+ y: 10.185,
157
+ },
158
+ width: 1.040000000000001,
159
+ height: 0.54,
160
+ pins: [
161
+ {
162
+ pinId: "D3.1",
163
+ x: 1.4433333333333334,
164
+ y: 10.185,
165
+ },
166
+ {
167
+ pinId: "D3.2",
168
+ x: 2.4833333333333343,
169
+ y: 10.185,
170
+ },
171
+ ],
172
+ },
173
+ {
174
+ chipId: "schematic_component_7",
175
+ center: {
176
+ x: 3.8100000000000005,
177
+ y: 3.715,
178
+ },
179
+ width: 1,
180
+ height: 0.45,
181
+ pins: [
182
+ {
183
+ pinId: "SW4.1",
184
+ x: 3.3100000000000005,
185
+ y: 3.665,
186
+ },
187
+ {
188
+ pinId: "SW4.2",
189
+ x: 4.3100000000000005,
190
+ y: 3.665,
191
+ },
192
+ ],
193
+ },
194
+ {
195
+ chipId: "schematic_component_8",
196
+ center: {
197
+ x: 2.6100000000000003,
198
+ y: 3.715,
199
+ },
200
+ width: 1.04,
201
+ height: 0.54,
202
+ pins: [
203
+ {
204
+ pinId: "D4.1",
205
+ x: 2.0900000000000003,
206
+ y: 3.715,
207
+ },
208
+ {
209
+ pinId: "D4.2",
210
+ x: 3.1300000000000003,
211
+ y: 3.715,
212
+ },
213
+ ],
214
+ },
215
+ {
216
+ chipId: "schematic_component_9",
217
+ center: {
218
+ x: 3.34,
219
+ y: 5.783333333333333,
220
+ },
221
+ width: 1,
222
+ height: 0.45,
223
+ pins: [
224
+ {
225
+ pinId: "SW5.1",
226
+ x: 2.84,
227
+ y: 5.733333333333333,
228
+ },
229
+ {
230
+ pinId: "SW5.2",
231
+ x: 3.84,
232
+ y: 5.733333333333333,
233
+ },
234
+ ],
235
+ },
236
+ {
237
+ chipId: "schematic_component_10",
238
+ center: {
239
+ x: 2.1399999999999997,
240
+ y: 5.783333333333333,
241
+ },
242
+ width: 1.040000000000001,
243
+ height: 0.54,
244
+ pins: [
245
+ {
246
+ pinId: "D5.1",
247
+ x: 1.6199999999999992,
248
+ y: 5.783333333333333,
249
+ },
250
+ {
251
+ pinId: "D5.2",
252
+ x: 2.66,
253
+ y: 5.783333333333333,
254
+ },
255
+ ],
256
+ },
257
+ {
258
+ chipId: "schematic_component_11",
259
+ center: {
260
+ x: 1.4249999999999998,
261
+ y: 2.17,
262
+ },
263
+ width: 1,
264
+ height: 0.45,
265
+ pins: [
266
+ {
267
+ pinId: "SW6.1",
268
+ x: 0.9249999999999998,
269
+ y: 2.12,
270
+ },
271
+ {
272
+ pinId: "SW6.2",
273
+ x: 1.9249999999999998,
274
+ y: 2.12,
275
+ },
276
+ ],
277
+ },
278
+ {
279
+ chipId: "schematic_component_12",
280
+ center: {
281
+ x: 0.22499999999999964,
282
+ y: 2.17,
283
+ },
284
+ width: 1.040000000000001,
285
+ height: 0.54,
286
+ pins: [
287
+ {
288
+ pinId: "D6.1",
289
+ x: -0.2950000000000008,
290
+ y: 2.17,
291
+ },
292
+ {
293
+ pinId: "D6.2",
294
+ x: 0.7450000000000001,
295
+ y: 2.17,
296
+ },
297
+ ],
298
+ },
299
+ {
300
+ chipId: "schematic_component_13",
301
+ center: {
302
+ x: 4.9799999999999995,
303
+ y: -3.4499999999999997,
304
+ },
305
+ width: 1,
306
+ height: 0.45,
307
+ pins: [
308
+ {
309
+ pinId: "SW7.1",
310
+ x: 4.4799999999999995,
311
+ y: -3.4999999999999996,
312
+ },
313
+ {
314
+ pinId: "SW7.2",
315
+ x: 5.4799999999999995,
316
+ y: -3.4999999999999996,
317
+ },
318
+ ],
319
+ },
320
+ {
321
+ chipId: "schematic_component_14",
322
+ center: {
323
+ x: 3.7799999999999994,
324
+ y: -3.4499999999999997,
325
+ },
326
+ width: 1.04,
327
+ height: 0.54,
328
+ pins: [
329
+ {
330
+ pinId: "D7.1",
331
+ x: 3.2599999999999993,
332
+ y: -3.4499999999999997,
333
+ },
334
+ {
335
+ pinId: "D7.2",
336
+ x: 4.299999999999999,
337
+ y: -3.4499999999999997,
338
+ },
339
+ ],
340
+ },
341
+ {
342
+ chipId: "schematic_component_15",
343
+ center: {
344
+ x: 2.944999999999998,
345
+ y: -6.048333333333334,
346
+ },
347
+ width: 1,
348
+ height: 0.45,
349
+ pins: [
350
+ {
351
+ pinId: "SW8.1",
352
+ x: 2.444999999999998,
353
+ y: -6.098333333333334,
354
+ },
355
+ {
356
+ pinId: "SW8.2",
357
+ x: 3.444999999999998,
358
+ y: -6.098333333333334,
359
+ },
360
+ ],
361
+ },
362
+ {
363
+ chipId: "schematic_component_16",
364
+ center: {
365
+ x: 1.744999999999998,
366
+ y: -6.048333333333334,
367
+ },
368
+ width: 1.04,
369
+ height: 0.54,
370
+ pins: [
371
+ {
372
+ pinId: "D8.1",
373
+ x: 1.224999999999998,
374
+ y: -6.048333333333334,
375
+ },
376
+ {
377
+ pinId: "D8.2",
378
+ x: 2.264999999999998,
379
+ y: -6.048333333333334,
380
+ },
381
+ ],
382
+ },
383
+ {
384
+ chipId: "schematic_component_17",
385
+ center: {
386
+ x: 4.409999999999998,
387
+ y: -7.788333333333336,
388
+ },
389
+ width: 1,
390
+ height: 0.45,
391
+ pins: [
392
+ {
393
+ pinId: "SW9.1",
394
+ x: 3.9099999999999984,
395
+ y: -7.838333333333335,
396
+ },
397
+ {
398
+ pinId: "SW9.2",
399
+ x: 4.909999999999998,
400
+ y: -7.838333333333335,
401
+ },
402
+ ],
403
+ },
404
+ {
405
+ chipId: "schematic_component_18",
406
+ center: {
407
+ x: 3.209999999999998,
408
+ y: -7.788333333333336,
409
+ },
410
+ width: 1.040000000000001,
411
+ height: 0.54,
412
+ pins: [
413
+ {
414
+ pinId: "D9.1",
415
+ x: 2.6899999999999977,
416
+ y: -7.788333333333336,
417
+ },
418
+ {
419
+ pinId: "D9.2",
420
+ x: 3.7299999999999986,
421
+ y: -7.788333333333336,
422
+ },
423
+ ],
424
+ },
425
+ ],
426
+ directConnections: [
427
+ {
428
+ pinIds: ["D1.2", "SW1.1"],
429
+ netId: ".D1 > .cathode to .SW1 > .pin1",
430
+ },
431
+ {
432
+ pinIds: ["D2.2", "SW2.1"],
433
+ netId: ".D2 > .cathode to .SW2 > .pin1",
434
+ },
435
+ {
436
+ pinIds: ["D3.2", "SW3.1"],
437
+ netId: ".D3 > .cathode to .SW3 > .pin1",
438
+ },
439
+ {
440
+ pinIds: ["D4.2", "SW4.1"],
441
+ netId: ".D4 > .cathode to .SW4 > .pin1",
442
+ },
443
+ {
444
+ pinIds: ["D5.2", "SW5.1"],
445
+ netId: ".D5 > .cathode to .SW5 > .pin1",
446
+ },
447
+ {
448
+ pinIds: ["D6.2", "SW6.1"],
449
+ netId: ".D6 > .cathode to .SW6 > .pin1",
450
+ },
451
+ {
452
+ pinIds: ["D7.2", "SW7.1"],
453
+ netId: ".D7 > .cathode to .SW7 > .pin1",
454
+ },
455
+ {
456
+ pinIds: ["D8.2", "SW8.1"],
457
+ netId: ".D8 > .cathode to .SW8 > .pin1",
458
+ },
459
+ {
460
+ pinIds: ["D9.2", "SW9.1"],
461
+ netId: ".D9 > .cathode to .SW9 > .pin1",
462
+ },
463
+ ],
464
+ netConnections: [
465
+ {
466
+ netId: "ROW0",
467
+ pinIds: ["J1.1", "D1.1", "D2.1", "D3.1"],
468
+ },
469
+ {
470
+ netId: "ROW1",
471
+ pinIds: ["J1.2", "D4.1", "D5.1", "D6.1"],
472
+ },
473
+ {
474
+ netId: "ROW2",
475
+ pinIds: ["J1.3", "D7.1", "D8.1", "D9.1"],
476
+ },
477
+ ],
478
+ availableNetLabelOrientations: {
479
+ ROW0: ["x-", "x+"],
480
+ ROW1: ["x-", "x+"],
481
+ ROW2: ["x-", "x+"],
482
+ },
483
+ maxMspPairDistance: 5,
484
+ }
485
+
486
+ export default () => <PipelineDebugger inputProblem={inputProblem} />
@@ -0,0 +1,490 @@
1
+ import type { InputProblem } from "lib/types/InputProblem"
2
+ import { test, expect } from "bun:test"
3
+ import { SchematicTracePipelineSolver } from "lib/index"
4
+
5
+ const inputProblem: InputProblem = {
6
+ chips: [
7
+ {
8
+ chipId: "schematic_component_0",
9
+ center: {
10
+ x: 0,
11
+ y: 0,
12
+ },
13
+ width: 2.3,
14
+ height: 1.4,
15
+ pins: [
16
+ {
17
+ pinId: "J1.1",
18
+ x: 1.15,
19
+ y: 0.5,
20
+ },
21
+ {
22
+ pinId: "J1.2",
23
+ x: 1.15,
24
+ y: 0.30000000000000004,
25
+ },
26
+ {
27
+ pinId: "J1.3",
28
+ x: 1.15,
29
+ y: 0.10000000000000009,
30
+ },
31
+ {
32
+ pinId: "J1.4",
33
+ x: 1.15,
34
+ y: -0.09999999999999998,
35
+ },
36
+ {
37
+ pinId: "J1.5",
38
+ x: 1.15,
39
+ y: -0.3,
40
+ },
41
+ {
42
+ pinId: "J1.6",
43
+ x: 1.15,
44
+ y: -0.5,
45
+ },
46
+ ],
47
+ },
48
+ {
49
+ chipId: "schematic_component_1",
50
+ center: {
51
+ x: 1.56,
52
+ y: 4.308333333333334,
53
+ },
54
+ width: 1,
55
+ height: 0.45,
56
+ pins: [
57
+ {
58
+ pinId: "SW1.1",
59
+ x: 1.06,
60
+ y: 4.258333333333334,
61
+ },
62
+ {
63
+ pinId: "SW1.2",
64
+ x: 2.06,
65
+ y: 4.258333333333334,
66
+ },
67
+ ],
68
+ },
69
+ {
70
+ chipId: "schematic_component_2",
71
+ center: {
72
+ x: 0.3599999999999999,
73
+ y: 4.308333333333334,
74
+ },
75
+ width: 1.04,
76
+ height: 0.54,
77
+ pins: [
78
+ {
79
+ pinId: "D1.1",
80
+ x: -0.16000000000000014,
81
+ y: 4.308333333333334,
82
+ },
83
+ {
84
+ pinId: "D1.2",
85
+ x: 0.8799999999999999,
86
+ y: 4.308333333333334,
87
+ },
88
+ ],
89
+ },
90
+ {
91
+ chipId: "schematic_component_3",
92
+ center: {
93
+ x: 5.06,
94
+ y: 0.3583333333333334,
95
+ },
96
+ width: 1,
97
+ height: 0.45,
98
+ pins: [
99
+ {
100
+ pinId: "SW2.1",
101
+ x: 4.56,
102
+ y: 0.30833333333333357,
103
+ },
104
+ {
105
+ pinId: "SW2.2",
106
+ x: 5.56,
107
+ y: 0.30833333333333357,
108
+ },
109
+ ],
110
+ },
111
+ {
112
+ chipId: "schematic_component_4",
113
+ center: {
114
+ x: 3.8599999999999994,
115
+ y: 0.3583333333333334,
116
+ },
117
+ width: 1.040000000000001,
118
+ height: 0.54,
119
+ pins: [
120
+ {
121
+ pinId: "D2.1",
122
+ x: 3.339999999999999,
123
+ y: 0.3583333333333334,
124
+ },
125
+ {
126
+ pinId: "D2.2",
127
+ x: 4.38,
128
+ y: 0.3583333333333334,
129
+ },
130
+ ],
131
+ },
132
+ {
133
+ chipId: "schematic_component_5",
134
+ center: {
135
+ x: 3.163333333333334,
136
+ y: 10.185,
137
+ },
138
+ width: 1,
139
+ height: 0.45,
140
+ pins: [
141
+ {
142
+ pinId: "SW3.1",
143
+ x: 2.663333333333334,
144
+ y: 10.135,
145
+ },
146
+ {
147
+ pinId: "SW3.2",
148
+ x: 3.663333333333334,
149
+ y: 10.135,
150
+ },
151
+ ],
152
+ },
153
+ {
154
+ chipId: "schematic_component_6",
155
+ center: {
156
+ x: 1.9633333333333338,
157
+ y: 10.185,
158
+ },
159
+ width: 1.040000000000001,
160
+ height: 0.54,
161
+ pins: [
162
+ {
163
+ pinId: "D3.1",
164
+ x: 1.4433333333333334,
165
+ y: 10.185,
166
+ },
167
+ {
168
+ pinId: "D3.2",
169
+ x: 2.4833333333333343,
170
+ y: 10.185,
171
+ },
172
+ ],
173
+ },
174
+ {
175
+ chipId: "schematic_component_7",
176
+ center: {
177
+ x: 3.8100000000000005,
178
+ y: 3.715,
179
+ },
180
+ width: 1,
181
+ height: 0.45,
182
+ pins: [
183
+ {
184
+ pinId: "SW4.1",
185
+ x: 3.3100000000000005,
186
+ y: 3.665,
187
+ },
188
+ {
189
+ pinId: "SW4.2",
190
+ x: 4.3100000000000005,
191
+ y: 3.665,
192
+ },
193
+ ],
194
+ },
195
+ {
196
+ chipId: "schematic_component_8",
197
+ center: {
198
+ x: 2.6100000000000003,
199
+ y: 3.715,
200
+ },
201
+ width: 1.04,
202
+ height: 0.54,
203
+ pins: [
204
+ {
205
+ pinId: "D4.1",
206
+ x: 2.0900000000000003,
207
+ y: 3.715,
208
+ },
209
+ {
210
+ pinId: "D4.2",
211
+ x: 3.1300000000000003,
212
+ y: 3.715,
213
+ },
214
+ ],
215
+ },
216
+ {
217
+ chipId: "schematic_component_9",
218
+ center: {
219
+ x: 3.34,
220
+ y: 5.783333333333333,
221
+ },
222
+ width: 1,
223
+ height: 0.45,
224
+ pins: [
225
+ {
226
+ pinId: "SW5.1",
227
+ x: 2.84,
228
+ y: 5.733333333333333,
229
+ },
230
+ {
231
+ pinId: "SW5.2",
232
+ x: 3.84,
233
+ y: 5.733333333333333,
234
+ },
235
+ ],
236
+ },
237
+ {
238
+ chipId: "schematic_component_10",
239
+ center: {
240
+ x: 2.1399999999999997,
241
+ y: 5.783333333333333,
242
+ },
243
+ width: 1.040000000000001,
244
+ height: 0.54,
245
+ pins: [
246
+ {
247
+ pinId: "D5.1",
248
+ x: 1.6199999999999992,
249
+ y: 5.783333333333333,
250
+ },
251
+ {
252
+ pinId: "D5.2",
253
+ x: 2.66,
254
+ y: 5.783333333333333,
255
+ },
256
+ ],
257
+ },
258
+ {
259
+ chipId: "schematic_component_11",
260
+ center: {
261
+ x: 1.4249999999999998,
262
+ y: 2.17,
263
+ },
264
+ width: 1,
265
+ height: 0.45,
266
+ pins: [
267
+ {
268
+ pinId: "SW6.1",
269
+ x: 0.9249999999999998,
270
+ y: 2.12,
271
+ },
272
+ {
273
+ pinId: "SW6.2",
274
+ x: 1.9249999999999998,
275
+ y: 2.12,
276
+ },
277
+ ],
278
+ },
279
+ {
280
+ chipId: "schematic_component_12",
281
+ center: {
282
+ x: 0.22499999999999964,
283
+ y: 2.17,
284
+ },
285
+ width: 1.040000000000001,
286
+ height: 0.54,
287
+ pins: [
288
+ {
289
+ pinId: "D6.1",
290
+ x: -0.2950000000000008,
291
+ y: 2.17,
292
+ },
293
+ {
294
+ pinId: "D6.2",
295
+ x: 0.7450000000000001,
296
+ y: 2.17,
297
+ },
298
+ ],
299
+ },
300
+ {
301
+ chipId: "schematic_component_13",
302
+ center: {
303
+ x: 4.9799999999999995,
304
+ y: -3.4499999999999997,
305
+ },
306
+ width: 1,
307
+ height: 0.45,
308
+ pins: [
309
+ {
310
+ pinId: "SW7.1",
311
+ x: 4.4799999999999995,
312
+ y: -3.4999999999999996,
313
+ },
314
+ {
315
+ pinId: "SW7.2",
316
+ x: 5.4799999999999995,
317
+ y: -3.4999999999999996,
318
+ },
319
+ ],
320
+ },
321
+ {
322
+ chipId: "schematic_component_14",
323
+ center: {
324
+ x: 3.7799999999999994,
325
+ y: -3.4499999999999997,
326
+ },
327
+ width: 1.04,
328
+ height: 0.54,
329
+ pins: [
330
+ {
331
+ pinId: "D7.1",
332
+ x: 3.2599999999999993,
333
+ y: -3.4499999999999997,
334
+ },
335
+ {
336
+ pinId: "D7.2",
337
+ x: 4.299999999999999,
338
+ y: -3.4499999999999997,
339
+ },
340
+ ],
341
+ },
342
+ {
343
+ chipId: "schematic_component_15",
344
+ center: {
345
+ x: 2.944999999999998,
346
+ y: -6.048333333333334,
347
+ },
348
+ width: 1,
349
+ height: 0.45,
350
+ pins: [
351
+ {
352
+ pinId: "SW8.1",
353
+ x: 2.444999999999998,
354
+ y: -6.098333333333334,
355
+ },
356
+ {
357
+ pinId: "SW8.2",
358
+ x: 3.444999999999998,
359
+ y: -6.098333333333334,
360
+ },
361
+ ],
362
+ },
363
+ {
364
+ chipId: "schematic_component_16",
365
+ center: {
366
+ x: 1.744999999999998,
367
+ y: -6.048333333333334,
368
+ },
369
+ width: 1.04,
370
+ height: 0.54,
371
+ pins: [
372
+ {
373
+ pinId: "D8.1",
374
+ x: 1.224999999999998,
375
+ y: -6.048333333333334,
376
+ },
377
+ {
378
+ pinId: "D8.2",
379
+ x: 2.264999999999998,
380
+ y: -6.048333333333334,
381
+ },
382
+ ],
383
+ },
384
+ {
385
+ chipId: "schematic_component_17",
386
+ center: {
387
+ x: 4.409999999999998,
388
+ y: -7.788333333333336,
389
+ },
390
+ width: 1,
391
+ height: 0.45,
392
+ pins: [
393
+ {
394
+ pinId: "SW9.1",
395
+ x: 3.9099999999999984,
396
+ y: -7.838333333333335,
397
+ },
398
+ {
399
+ pinId: "SW9.2",
400
+ x: 4.909999999999998,
401
+ y: -7.838333333333335,
402
+ },
403
+ ],
404
+ },
405
+ {
406
+ chipId: "schematic_component_18",
407
+ center: {
408
+ x: 3.209999999999998,
409
+ y: -7.788333333333336,
410
+ },
411
+ width: 1.040000000000001,
412
+ height: 0.54,
413
+ pins: [
414
+ {
415
+ pinId: "D9.1",
416
+ x: 2.6899999999999977,
417
+ y: -7.788333333333336,
418
+ },
419
+ {
420
+ pinId: "D9.2",
421
+ x: 3.7299999999999986,
422
+ y: -7.788333333333336,
423
+ },
424
+ ],
425
+ },
426
+ ],
427
+ directConnections: [
428
+ {
429
+ pinIds: ["D1.2", "SW1.1"],
430
+ netId: ".D1 > .cathode to .SW1 > .pin1",
431
+ },
432
+ {
433
+ pinIds: ["D2.2", "SW2.1"],
434
+ netId: ".D2 > .cathode to .SW2 > .pin1",
435
+ },
436
+ {
437
+ pinIds: ["D3.2", "SW3.1"],
438
+ netId: ".D3 > .cathode to .SW3 > .pin1",
439
+ },
440
+ {
441
+ pinIds: ["D4.2", "SW4.1"],
442
+ netId: ".D4 > .cathode to .SW4 > .pin1",
443
+ },
444
+ {
445
+ pinIds: ["D5.2", "SW5.1"],
446
+ netId: ".D5 > .cathode to .SW5 > .pin1",
447
+ },
448
+ {
449
+ pinIds: ["D6.2", "SW6.1"],
450
+ netId: ".D6 > .cathode to .SW6 > .pin1",
451
+ },
452
+ {
453
+ pinIds: ["D7.2", "SW7.1"],
454
+ netId: ".D7 > .cathode to .SW7 > .pin1",
455
+ },
456
+ {
457
+ pinIds: ["D8.2", "SW8.1"],
458
+ netId: ".D8 > .cathode to .SW8 > .pin1",
459
+ },
460
+ {
461
+ pinIds: ["D9.2", "SW9.1"],
462
+ netId: ".D9 > .cathode to .SW9 > .pin1",
463
+ },
464
+ ],
465
+ netConnections: [
466
+ {
467
+ netId: "ROW0",
468
+ pinIds: ["J1.1", "D1.1", "D2.1", "D3.1"],
469
+ },
470
+ {
471
+ netId: "ROW1",
472
+ pinIds: ["J1.2", "D4.1", "D5.1", "D6.1"],
473
+ },
474
+ {
475
+ netId: "ROW2",
476
+ pinIds: ["J1.3", "D7.1", "D8.1", "D9.1"],
477
+ },
478
+ ],
479
+ availableNetLabelOrientations: {
480
+ ROW0: ["x-", "x+"],
481
+ ROW1: ["x-", "x+"],
482
+ ROW2: ["x-", "x+"],
483
+ },
484
+ maxMspPairDistance: 5,
485
+ }
486
+
487
+ test("SchematicTracePipelineSolver_repro03 - infinite loop fixed", () => {
488
+ const solver = new SchematicTracePipelineSolver(inputProblem)
489
+ solver.solve()
490
+ })