@stevenvo780/st-lang 4.10.0 → 4.11.0

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.
Files changed (121) hide show
  1. package/dist/proof-systems/distributed-exchange/index.d.ts +101 -0
  2. package/dist/proof-systems/distributed-exchange/index.d.ts.map +1 -0
  3. package/dist/proof-systems/distributed-exchange/index.js +408 -0
  4. package/dist/proof-systems/distributed-exchange/index.js.map +1 -0
  5. package/dist/reasoning/graph-theory/index.d.ts +63 -0
  6. package/dist/reasoning/graph-theory/index.d.ts.map +1 -0
  7. package/dist/reasoning/graph-theory/index.js +1043 -0
  8. package/dist/reasoning/graph-theory/index.js.map +1 -0
  9. package/dist/reasoning/group-presentation/cayley.d.ts +8 -0
  10. package/dist/reasoning/group-presentation/cayley.d.ts.map +1 -0
  11. package/dist/reasoning/group-presentation/cayley.js +38 -0
  12. package/dist/reasoning/group-presentation/cayley.js.map +1 -0
  13. package/dist/reasoning/group-presentation/index.d.ts +8 -0
  14. package/dist/reasoning/group-presentation/index.d.ts.map +1 -0
  15. package/dist/reasoning/group-presentation/index.js +36 -0
  16. package/dist/reasoning/group-presentation/index.js.map +1 -0
  17. package/dist/reasoning/group-presentation/standard-groups.d.ts +6 -0
  18. package/dist/reasoning/group-presentation/standard-groups.d.ts.map +1 -0
  19. package/dist/reasoning/group-presentation/standard-groups.js +93 -0
  20. package/dist/reasoning/group-presentation/standard-groups.js.map +1 -0
  21. package/dist/reasoning/group-presentation/todd-coxeter.d.ts +10 -0
  22. package/dist/reasoning/group-presentation/todd-coxeter.d.ts.map +1 -0
  23. package/dist/reasoning/group-presentation/todd-coxeter.js +362 -0
  24. package/dist/reasoning/group-presentation/todd-coxeter.js.map +1 -0
  25. package/dist/reasoning/group-presentation/types.d.ts +7 -0
  26. package/dist/reasoning/group-presentation/types.d.ts.map +1 -0
  27. package/dist/reasoning/group-presentation/types.js +22 -0
  28. package/dist/reasoning/group-presentation/types.js.map +1 -0
  29. package/dist/reasoning/group-presentation/words.d.ts +10 -0
  30. package/dist/reasoning/group-presentation/words.d.ts.map +1 -0
  31. package/dist/reasoning/group-presentation/words.js +109 -0
  32. package/dist/reasoning/group-presentation/words.js.map +1 -0
  33. package/dist/tests/proof-systems/distributed-exchange/distributed-exchange.test.d.ts +2 -0
  34. package/dist/tests/proof-systems/distributed-exchange/distributed-exchange.test.d.ts.map +1 -0
  35. package/dist/tests/proof-systems/distributed-exchange/distributed-exchange.test.js +328 -0
  36. package/dist/tests/proof-systems/distributed-exchange/distributed-exchange.test.js.map +1 -0
  37. package/dist/tests/reasoning/graph-theory/graph-theory.test.d.ts +2 -0
  38. package/dist/tests/reasoning/graph-theory/graph-theory.test.d.ts.map +1 -0
  39. package/dist/tests/reasoning/graph-theory/graph-theory.test.js +363 -0
  40. package/dist/tests/reasoning/graph-theory/graph-theory.test.js.map +1 -0
  41. package/dist/tests/reasoning/group-presentation/group-presentation.test.d.ts +2 -0
  42. package/dist/tests/reasoning/group-presentation/group-presentation.test.d.ts.map +1 -0
  43. package/dist/tests/reasoning/group-presentation/group-presentation.test.js +229 -0
  44. package/dist/tests/reasoning/group-presentation/group-presentation.test.js.map +1 -0
  45. package/dist/tests/tooling/exporters/coq-v2/coq-v2-exporter.test.d.ts +2 -0
  46. package/dist/tests/tooling/exporters/coq-v2/coq-v2-exporter.test.d.ts.map +1 -0
  47. package/dist/tests/tooling/exporters/coq-v2/coq-v2-exporter.test.js +411 -0
  48. package/dist/tests/tooling/exporters/coq-v2/coq-v2-exporter.test.js.map +1 -0
  49. package/dist/tests/tooling/lemma-library/lemma-library.test.d.ts +2 -0
  50. package/dist/tests/tooling/lemma-library/lemma-library.test.d.ts.map +1 -0
  51. package/dist/tests/tooling/lemma-library/lemma-library.test.js +197 -0
  52. package/dist/tests/tooling/lemma-library/lemma-library.test.js.map +1 -0
  53. package/dist/tests/tooling/provenance/ledger.test.d.ts +2 -0
  54. package/dist/tests/tooling/provenance/ledger.test.d.ts.map +1 -0
  55. package/dist/tests/tooling/provenance/ledger.test.js +545 -0
  56. package/dist/tests/tooling/provenance/ledger.test.js.map +1 -0
  57. package/dist/tooling/exporters/coq-v2/index.d.ts +68 -0
  58. package/dist/tooling/exporters/coq-v2/index.d.ts.map +1 -0
  59. package/dist/tooling/exporters/coq-v2/index.js +692 -0
  60. package/dist/tooling/exporters/coq-v2/index.js.map +1 -0
  61. package/dist/tooling/lemma-library/apply.d.ts +9 -0
  62. package/dist/tooling/lemma-library/apply.d.ts.map +1 -0
  63. package/dist/tooling/lemma-library/apply.js +94 -0
  64. package/dist/tooling/lemma-library/apply.js.map +1 -0
  65. package/dist/tooling/lemma-library/arithmetic.d.ts +3 -0
  66. package/dist/tooling/lemma-library/arithmetic.d.ts.map +1 -0
  67. package/dist/tooling/lemma-library/arithmetic.js +176 -0
  68. package/dist/tooling/lemma-library/arithmetic.js.map +1 -0
  69. package/dist/tooling/lemma-library/firstorder.d.ts +3 -0
  70. package/dist/tooling/lemma-library/firstorder.d.ts.map +1 -0
  71. package/dist/tooling/lemma-library/firstorder.js +136 -0
  72. package/dist/tooling/lemma-library/firstorder.js.map +1 -0
  73. package/dist/tooling/lemma-library/index.d.ts +13 -0
  74. package/dist/tooling/lemma-library/index.d.ts.map +1 -0
  75. package/dist/tooling/lemma-library/index.js +32 -0
  76. package/dist/tooling/lemma-library/index.js.map +1 -0
  77. package/dist/tooling/lemma-library/library.d.ts +34 -0
  78. package/dist/tooling/lemma-library/library.d.ts.map +1 -0
  79. package/dist/tooling/lemma-library/library.js +126 -0
  80. package/dist/tooling/lemma-library/library.js.map +1 -0
  81. package/dist/tooling/lemma-library/modal.d.ts +3 -0
  82. package/dist/tooling/lemma-library/modal.d.ts.map +1 -0
  83. package/dist/tooling/lemma-library/modal.js +138 -0
  84. package/dist/tooling/lemma-library/modal.js.map +1 -0
  85. package/dist/tooling/lemma-library/propositional.d.ts +3 -0
  86. package/dist/tooling/lemma-library/propositional.d.ts.map +1 -0
  87. package/dist/tooling/lemma-library/propositional.js +265 -0
  88. package/dist/tooling/lemma-library/propositional.js.map +1 -0
  89. package/dist/tooling/lemma-library/set-theory.d.ts +3 -0
  90. package/dist/tooling/lemma-library/set-theory.d.ts.map +1 -0
  91. package/dist/tooling/lemma-library/set-theory.js +134 -0
  92. package/dist/tooling/lemma-library/set-theory.js.map +1 -0
  93. package/dist/tooling/lemma-library/standard.d.ts +3 -0
  94. package/dist/tooling/lemma-library/standard.d.ts.map +1 -0
  95. package/dist/tooling/lemma-library/standard.js +27 -0
  96. package/dist/tooling/lemma-library/standard.js.map +1 -0
  97. package/dist/tooling/lemma-library/tfidf.d.ts +5 -0
  98. package/dist/tooling/lemma-library/tfidf.d.ts.map +1 -0
  99. package/dist/tooling/lemma-library/tfidf.js +100 -0
  100. package/dist/tooling/lemma-library/tfidf.js.map +1 -0
  101. package/dist/tooling/lemma-library/tokenize.d.ts +2 -0
  102. package/dist/tooling/lemma-library/tokenize.d.ts.map +1 -0
  103. package/dist/tooling/lemma-library/tokenize.js +74 -0
  104. package/dist/tooling/lemma-library/tokenize.js.map +1 -0
  105. package/dist/tooling/lemma-library/types.d.ts +53 -0
  106. package/dist/tooling/lemma-library/types.d.ts.map +1 -0
  107. package/dist/tooling/lemma-library/types.js +10 -0
  108. package/dist/tooling/lemma-library/types.js.map +1 -0
  109. package/dist/tooling/provenance/index.d.ts +3 -0
  110. package/dist/tooling/provenance/index.d.ts.map +1 -0
  111. package/dist/tooling/provenance/index.js +16 -0
  112. package/dist/tooling/provenance/index.js.map +1 -0
  113. package/dist/tooling/provenance/ledger.d.ts +89 -0
  114. package/dist/tooling/provenance/ledger.d.ts.map +1 -0
  115. package/dist/tooling/provenance/ledger.js +439 -0
  116. package/dist/tooling/provenance/ledger.js.map +1 -0
  117. package/dist/tooling/provenance/types.d.ts +70 -0
  118. package/dist/tooling/provenance/types.d.ts.map +1 -0
  119. package/dist/tooling/provenance/types.js +14 -0
  120. package/dist/tooling/provenance/types.js.map +1 -0
  121. package/package.json +1 -1
@@ -0,0 +1,1043 @@
1
+ "use strict";
2
+ // ============================================================
3
+ // ST Graph Theory — grafos finitos, recorridos y algoritmos clásicos
4
+ // ============================================================
5
+ //
6
+ // Implementa una representación genérica de grafos dirigidos y no
7
+ // dirigidos sobre vértices arbitrarios `V` (comparables por igualdad
8
+ // estructural cuando son primitivos, o por identidad cuando son
9
+ // objetos). Cubre:
10
+ //
11
+ // • BFS / DFS / orden topológico
12
+ // • Componentes conexos y fuertemente conexos (Tarjan)
13
+ // • Puntos de articulación y puentes (DFS lowlink)
14
+ // • Caminos mínimos: Dijkstra (no negativos), Bellman-Ford
15
+ // (detecta ciclos negativos), Floyd-Warshall (todos contra todos)
16
+ // • Árbol generador mínimo: Kruskal (DSU) y Prim (cola por prioridad
17
+ // simple)
18
+ // • Emparejamiento bipartito máximo: Hopcroft-Karp y variante
19
+ // determinista por aumento de caminos
20
+ // • Coloreo: greedy y número cromático por backtracking
21
+ // • Isomorfismo (grafos pequeños) por refinamiento de invariantes y
22
+ // backtracking compatibles con grados/sequence
23
+ //
24
+ // Convenciones:
25
+ // • `Graph<V>` mantiene `vertices: Set<V>` y `edges: Array<Edge>`.
26
+ // Para grafos no dirigidos cada arista lógica se almacena una sola
27
+ // vez; `neighbors` la recorre en ambos sentidos. Para dirigidos,
28
+ // la dirección manda.
29
+ // • Los pesos por defecto son 1; los algoritmos de caminos mínimos
30
+ // y MST asumen pesos finitos definidos.
31
+ // • La igualdad de vértices se hace con `===` (apta para strings,
32
+ // números, símbolos y referencias). Para objetos compuestos, el
33
+ // llamante debe deduplicar antes.
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.makeGraph = makeGraph;
36
+ exports.addVertex = addVertex;
37
+ exports.addEdge = addEdge;
38
+ exports.neighbors = neighbors;
39
+ exports.inDegree = inDegree;
40
+ exports.outDegree = outDegree;
41
+ exports.bfs = bfs;
42
+ exports.dfs = dfs;
43
+ exports.topologicalSort = topologicalSort;
44
+ exports.connectedComponents = connectedComponents;
45
+ exports.isConnected = isConnected;
46
+ exports.stronglyConnectedComponents = stronglyConnectedComponents;
47
+ exports.articulationPoints = articulationPoints;
48
+ exports.bridges = bridges;
49
+ exports.dijkstra = dijkstra;
50
+ exports.bellmanFord = bellmanFord;
51
+ exports.floydWarshall = floydWarshall;
52
+ exports.kruskal = kruskal;
53
+ exports.prim = prim;
54
+ exports.bipartiteMaximumMatching = bipartiteMaximumMatching;
55
+ exports.hopcroftKarp = hopcroftKarp;
56
+ exports.greedyColoring = greedyColoring;
57
+ exports.chromaticNumber = chromaticNumber;
58
+ exports.areIsomorphic = areIsomorphic;
59
+ exports.findIsomorphism = findIsomorphism;
60
+ // ------------------------------------------------------------
61
+ // Construcción
62
+ // ------------------------------------------------------------
63
+ function makeGraph(directed = false) {
64
+ return {
65
+ vertices: new Set(),
66
+ edges: [],
67
+ directed,
68
+ };
69
+ }
70
+ function addVertex(G, v) {
71
+ G.vertices.add(v);
72
+ }
73
+ function addEdge(G, e) {
74
+ G.vertices.add(e.from);
75
+ G.vertices.add(e.to);
76
+ G.edges.push({ from: e.from, to: e.to, weight: e.weight });
77
+ }
78
+ // Vecinos salientes (en no dirigido, ambos extremos cuentan).
79
+ function neighbors(G, v) {
80
+ const out = [];
81
+ for (const e of G.edges) {
82
+ if (e.from === v)
83
+ out.push(e.to);
84
+ else if (!G.directed && e.to === v)
85
+ out.push(e.from);
86
+ }
87
+ return out;
88
+ }
89
+ function inDegree(G, v) {
90
+ if (!G.directed)
91
+ return degreeUndirected(G, v);
92
+ let d = 0;
93
+ for (const e of G.edges)
94
+ if (e.to === v)
95
+ d++;
96
+ return d;
97
+ }
98
+ function outDegree(G, v) {
99
+ if (!G.directed)
100
+ return degreeUndirected(G, v);
101
+ let d = 0;
102
+ for (const e of G.edges)
103
+ if (e.from === v)
104
+ d++;
105
+ return d;
106
+ }
107
+ function degreeUndirected(G, v) {
108
+ let d = 0;
109
+ for (const e of G.edges) {
110
+ if (e.from === v)
111
+ d++;
112
+ if (e.to === v && e.from !== e.to)
113
+ d++;
114
+ }
115
+ return d;
116
+ }
117
+ function buildAdjacency(G) {
118
+ const adj = new Map();
119
+ for (const v of G.vertices)
120
+ adj.set(v, []);
121
+ for (const e of G.edges) {
122
+ const w = e.weight ?? 1;
123
+ const a = adj.get(e.from);
124
+ if (a)
125
+ a.push({ to: e.to, weight: w });
126
+ if (!G.directed && e.from !== e.to) {
127
+ const b = adj.get(e.to);
128
+ if (b)
129
+ b.push({ to: e.from, weight: w });
130
+ }
131
+ }
132
+ return adj;
133
+ }
134
+ // ------------------------------------------------------------
135
+ // Recorridos
136
+ // ------------------------------------------------------------
137
+ function bfs(G, start, visit) {
138
+ if (!G.vertices.has(start))
139
+ return [];
140
+ const adj = buildAdjacency(G);
141
+ const order = [];
142
+ const seen = new Set([start]);
143
+ const queue = [start];
144
+ let head = 0;
145
+ while (head < queue.length) {
146
+ const v = queue[head++];
147
+ order.push(v);
148
+ if (visit)
149
+ visit(v);
150
+ const nbrs = adj.get(v) ?? [];
151
+ for (const { to } of nbrs) {
152
+ if (!seen.has(to)) {
153
+ seen.add(to);
154
+ queue.push(to);
155
+ }
156
+ }
157
+ }
158
+ return order;
159
+ }
160
+ function dfs(G, start, visit) {
161
+ if (!G.vertices.has(start))
162
+ return [];
163
+ const adj = buildAdjacency(G);
164
+ const order = [];
165
+ const seen = new Set();
166
+ const stack = [start];
167
+ while (stack.length > 0) {
168
+ const v = stack.pop();
169
+ if (seen.has(v))
170
+ continue;
171
+ seen.add(v);
172
+ order.push(v);
173
+ if (visit)
174
+ visit(v);
175
+ const nbrs = adj.get(v) ?? [];
176
+ // Apilar en orden inverso para que el primer vecino se procese primero.
177
+ for (let i = nbrs.length - 1; i >= 0; i--) {
178
+ const entry = nbrs[i];
179
+ if (entry && !seen.has(entry.to))
180
+ stack.push(entry.to);
181
+ }
182
+ }
183
+ return order;
184
+ }
185
+ // Orden topológico vía Kahn. Devuelve `has-cycle` si no es DAG.
186
+ function topologicalSort(G) {
187
+ if (!G.directed) {
188
+ // Para no dirigidos no tiene sentido salvo aristas-cero; devolver vértices.
189
+ return Array.from(G.vertices);
190
+ }
191
+ const inDeg = new Map();
192
+ for (const v of G.vertices)
193
+ inDeg.set(v, 0);
194
+ const adj = buildAdjacency(G);
195
+ for (const e of G.edges) {
196
+ inDeg.set(e.to, (inDeg.get(e.to) ?? 0) + 1);
197
+ }
198
+ const queue = [];
199
+ for (const [v, d] of inDeg)
200
+ if (d === 0)
201
+ queue.push(v);
202
+ const order = [];
203
+ let head = 0;
204
+ while (head < queue.length) {
205
+ const v = queue[head++];
206
+ order.push(v);
207
+ const nbrs = adj.get(v) ?? [];
208
+ for (const { to } of nbrs) {
209
+ const nd = (inDeg.get(to) ?? 0) - 1;
210
+ inDeg.set(to, nd);
211
+ if (nd === 0)
212
+ queue.push(to);
213
+ }
214
+ }
215
+ if (order.length !== G.vertices.size)
216
+ return 'has-cycle';
217
+ return order;
218
+ }
219
+ // ------------------------------------------------------------
220
+ // Conectividad
221
+ // ------------------------------------------------------------
222
+ function connectedComponents(G) {
223
+ const adj = buildAdjacency(G);
224
+ const seen = new Set();
225
+ const comps = [];
226
+ for (const start of G.vertices) {
227
+ if (seen.has(start))
228
+ continue;
229
+ const comp = [];
230
+ const stack = [start];
231
+ while (stack.length > 0) {
232
+ const v = stack.pop();
233
+ if (seen.has(v))
234
+ continue;
235
+ seen.add(v);
236
+ comp.push(v);
237
+ // En grafos dirigidos, para conectividad "débil" usamos vecinos en ambos
238
+ // sentidos; para no dirigidos, `adj` ya recorre ambos extremos.
239
+ const nbrs = adj.get(v) ?? [];
240
+ for (const { to } of nbrs)
241
+ if (!seen.has(to))
242
+ stack.push(to);
243
+ if (G.directed) {
244
+ // Añadir predecesores también para conectividad débil.
245
+ for (const e of G.edges)
246
+ if (e.to === v && !seen.has(e.from))
247
+ stack.push(e.from);
248
+ }
249
+ }
250
+ comps.push(comp);
251
+ }
252
+ return comps;
253
+ }
254
+ function isConnected(G) {
255
+ if (G.vertices.size <= 1)
256
+ return true;
257
+ return connectedComponents(G).length === 1;
258
+ }
259
+ // Tarjan SCC en grafos dirigidos. Para no dirigidos cada SCC coincide con
260
+ // el componente conexo.
261
+ function stronglyConnectedComponents(G) {
262
+ if (!G.directed)
263
+ return connectedComponents(G);
264
+ const adj = buildAdjacency(G);
265
+ const index = new Map();
266
+ const lowlink = new Map();
267
+ const onStack = new Set();
268
+ const stack = [];
269
+ const result = [];
270
+ let counter = 0;
271
+ const callStack = [];
272
+ for (const start of G.vertices) {
273
+ if (index.has(start))
274
+ continue;
275
+ callStack.push({ v: start, iter: 0 });
276
+ index.set(start, counter);
277
+ lowlink.set(start, counter);
278
+ counter++;
279
+ stack.push(start);
280
+ onStack.add(start);
281
+ while (callStack.length > 0) {
282
+ const frame = callStack[callStack.length - 1];
283
+ const v = frame.v;
284
+ const nbrs = adj.get(v) ?? [];
285
+ if (frame.iter < nbrs.length) {
286
+ const entry = nbrs[frame.iter];
287
+ frame.iter++;
288
+ const w = entry.to;
289
+ if (!index.has(w)) {
290
+ index.set(w, counter);
291
+ lowlink.set(w, counter);
292
+ counter++;
293
+ stack.push(w);
294
+ onStack.add(w);
295
+ callStack.push({ v: w, iter: 0 });
296
+ }
297
+ else if (onStack.has(w)) {
298
+ const lv = lowlink.get(v) ?? 0;
299
+ const iw = index.get(w) ?? 0;
300
+ if (iw < lv)
301
+ lowlink.set(v, iw);
302
+ }
303
+ }
304
+ else {
305
+ // Cerrar el nodo: si lowlink == index → raíz de SCC.
306
+ const lv = lowlink.get(v) ?? 0;
307
+ const iv = index.get(v) ?? 0;
308
+ if (lv === iv) {
309
+ const comp = [];
310
+ while (stack.length > 0) {
311
+ const w = stack.pop();
312
+ onStack.delete(w);
313
+ comp.push(w);
314
+ if (w === v)
315
+ break;
316
+ }
317
+ result.push(comp);
318
+ }
319
+ callStack.pop();
320
+ if (callStack.length > 0) {
321
+ const parent = callStack[callStack.length - 1];
322
+ const lp = lowlink.get(parent.v) ?? 0;
323
+ if (lv < lp)
324
+ lowlink.set(parent.v, lv);
325
+ }
326
+ }
327
+ }
328
+ }
329
+ return result;
330
+ }
331
+ // Articulation points (corte) en grafos no dirigidos por DFS lowlink.
332
+ function articulationPoints(G) {
333
+ if (G.vertices.size === 0)
334
+ return [];
335
+ const adj = buildAdjacency(G);
336
+ const disc = new Map();
337
+ const low = new Map();
338
+ const parent = new Map();
339
+ const isArt = new Set();
340
+ let timer = 0;
341
+ for (const start of G.vertices) {
342
+ if (disc.has(start))
343
+ continue;
344
+ const root = start;
345
+ const stack = [{ v: root, iter: 0, children: 0 }];
346
+ disc.set(root, timer);
347
+ low.set(root, timer);
348
+ timer++;
349
+ parent.set(root, null);
350
+ while (stack.length > 0) {
351
+ const frame = stack[stack.length - 1];
352
+ const v = frame.v;
353
+ const nbrs = adj.get(v) ?? [];
354
+ if (frame.iter < nbrs.length) {
355
+ const entry = nbrs[frame.iter];
356
+ frame.iter++;
357
+ const w = entry.to;
358
+ if (!disc.has(w)) {
359
+ frame.children++;
360
+ parent.set(w, v);
361
+ disc.set(w, timer);
362
+ low.set(w, timer);
363
+ timer++;
364
+ stack.push({ v: w, iter: 0, children: 0 });
365
+ }
366
+ else if (w !== parent.get(v)) {
367
+ const lv = low.get(v) ?? 0;
368
+ const dw = disc.get(w) ?? 0;
369
+ if (dw < lv)
370
+ low.set(v, dw);
371
+ }
372
+ }
373
+ else {
374
+ stack.pop();
375
+ const p = parent.get(v);
376
+ if (p != null) {
377
+ const lp = low.get(p) ?? 0;
378
+ const lv = low.get(v) ?? 0;
379
+ if (lv < lp)
380
+ low.set(p, lv);
381
+ const dp = disc.get(p) ?? 0;
382
+ if (p !== root && lv >= dp)
383
+ isArt.add(p);
384
+ }
385
+ else {
386
+ // raíz
387
+ if (frame.children > 1)
388
+ isArt.add(v);
389
+ }
390
+ }
391
+ }
392
+ }
393
+ return Array.from(isArt);
394
+ }
395
+ // Puentes en grafo no dirigido (DFS lowlink). Devuelve aristas (a,b).
396
+ function bridges(G) {
397
+ const adj = buildAdjacency(G);
398
+ const disc = new Map();
399
+ const low = new Map();
400
+ const parent = new Map();
401
+ const out = [];
402
+ let timer = 0;
403
+ for (const start of G.vertices) {
404
+ if (disc.has(start))
405
+ continue;
406
+ const stack = [{ v: start, iter: 0 }];
407
+ disc.set(start, timer);
408
+ low.set(start, timer);
409
+ timer++;
410
+ parent.set(start, null);
411
+ while (stack.length > 0) {
412
+ const frame = stack[stack.length - 1];
413
+ const v = frame.v;
414
+ const nbrs = adj.get(v) ?? [];
415
+ if (frame.iter < nbrs.length) {
416
+ const entry = nbrs[frame.iter];
417
+ frame.iter++;
418
+ const w = entry.to;
419
+ if (!disc.has(w)) {
420
+ parent.set(w, v);
421
+ disc.set(w, timer);
422
+ low.set(w, timer);
423
+ timer++;
424
+ stack.push({ v: w, iter: 0 });
425
+ }
426
+ else if (w !== parent.get(v)) {
427
+ const lv = low.get(v) ?? 0;
428
+ const dw = disc.get(w) ?? 0;
429
+ if (dw < lv)
430
+ low.set(v, dw);
431
+ }
432
+ }
433
+ else {
434
+ stack.pop();
435
+ const p = parent.get(v);
436
+ if (p != null) {
437
+ const lp = low.get(p) ?? 0;
438
+ const lv = low.get(v) ?? 0;
439
+ if (lv < lp)
440
+ low.set(p, lv);
441
+ const dp = disc.get(p) ?? 0;
442
+ if (lv > dp)
443
+ out.push({ from: p, to: v });
444
+ }
445
+ }
446
+ }
447
+ }
448
+ return out;
449
+ }
450
+ // ------------------------------------------------------------
451
+ // Caminos mínimos
452
+ // ------------------------------------------------------------
453
+ // Min-heap binario para Dijkstra. Items: [distancia, vértice].
454
+ class MinHeap {
455
+ data = [];
456
+ get size() {
457
+ return this.data.length;
458
+ }
459
+ push(item) {
460
+ this.data.push(item);
461
+ this.siftUp(this.data.length - 1);
462
+ }
463
+ pop() {
464
+ const n = this.data.length;
465
+ if (n === 0)
466
+ return undefined;
467
+ const top = this.data[0];
468
+ const last = this.data.pop();
469
+ if (n > 1) {
470
+ this.data[0] = last;
471
+ this.siftDown(0);
472
+ }
473
+ return top;
474
+ }
475
+ siftUp(i) {
476
+ let idx = i;
477
+ while (idx > 0) {
478
+ const parent = (idx - 1) >> 1;
479
+ const pa = this.data[parent];
480
+ const cu = this.data[idx];
481
+ if (cu[0] < pa[0]) {
482
+ this.data[idx] = pa;
483
+ this.data[parent] = cu;
484
+ idx = parent;
485
+ }
486
+ else
487
+ break;
488
+ }
489
+ }
490
+ siftDown(i) {
491
+ let idx = i;
492
+ const n = this.data.length;
493
+ while (true) {
494
+ const l = 2 * idx + 1;
495
+ const r = 2 * idx + 2;
496
+ let best = idx;
497
+ if (l < n && this.data[l][0] < this.data[best][0])
498
+ best = l;
499
+ if (r < n && this.data[r][0] < this.data[best][0])
500
+ best = r;
501
+ if (best !== idx) {
502
+ const tmp = this.data[idx];
503
+ this.data[idx] = this.data[best];
504
+ this.data[best] = tmp;
505
+ idx = best;
506
+ }
507
+ else
508
+ break;
509
+ }
510
+ }
511
+ }
512
+ function dijkstra(G, start) {
513
+ // Validar pesos no negativos.
514
+ for (const e of G.edges) {
515
+ if ((e.weight ?? 1) < 0) {
516
+ throw new Error('dijkstra: pesos negativos no permitidos');
517
+ }
518
+ }
519
+ const adj = buildAdjacency(G);
520
+ const dist = new Map();
521
+ const pred = new Map();
522
+ for (const v of G.vertices)
523
+ dist.set(v, Infinity);
524
+ if (!G.vertices.has(start))
525
+ return { distances: dist, predecessors: pred };
526
+ dist.set(start, 0);
527
+ const heap = new MinHeap();
528
+ heap.push([0, start]);
529
+ while (heap.size > 0) {
530
+ const top = heap.pop();
531
+ if (!top)
532
+ break;
533
+ const [d, v] = top;
534
+ if (d > (dist.get(v) ?? Infinity))
535
+ continue;
536
+ const nbrs = adj.get(v) ?? [];
537
+ for (const { to, weight } of nbrs) {
538
+ const nd = d + weight;
539
+ if (nd < (dist.get(to) ?? Infinity)) {
540
+ dist.set(to, nd);
541
+ pred.set(to, v);
542
+ heap.push([nd, to]);
543
+ }
544
+ }
545
+ }
546
+ return { distances: dist, predecessors: pred };
547
+ }
548
+ function bellmanFord(G, start) {
549
+ const dist = new Map();
550
+ const pred = new Map();
551
+ for (const v of G.vertices)
552
+ dist.set(v, Infinity);
553
+ if (!G.vertices.has(start))
554
+ return { distances: dist, predecessors: pred, negativeCycle: false };
555
+ dist.set(start, 0);
556
+ // Lista de aristas dirigidas equivalentes: para no dirigidos, duplicamos.
557
+ const dEdges = [];
558
+ for (const e of G.edges) {
559
+ const w = e.weight ?? 1;
560
+ dEdges.push({ from: e.from, to: e.to, weight: w });
561
+ if (!G.directed && e.from !== e.to)
562
+ dEdges.push({ from: e.to, to: e.from, weight: w });
563
+ }
564
+ const n = G.vertices.size;
565
+ for (let i = 0; i < n - 1; i++) {
566
+ let changed = false;
567
+ for (const e of dEdges) {
568
+ const du = dist.get(e.from) ?? Infinity;
569
+ if (du === Infinity)
570
+ continue;
571
+ const nd = du + e.weight;
572
+ if (nd < (dist.get(e.to) ?? Infinity)) {
573
+ dist.set(e.to, nd);
574
+ pred.set(e.to, e.from);
575
+ changed = true;
576
+ }
577
+ }
578
+ if (!changed)
579
+ break;
580
+ }
581
+ // Detectar ciclo negativo: si todavía se puede relajar.
582
+ let negativeCycle = false;
583
+ for (const e of dEdges) {
584
+ const du = dist.get(e.from) ?? Infinity;
585
+ if (du === Infinity)
586
+ continue;
587
+ if (du + e.weight < (dist.get(e.to) ?? Infinity)) {
588
+ negativeCycle = true;
589
+ break;
590
+ }
591
+ }
592
+ return { distances: dist, predecessors: pred, negativeCycle };
593
+ }
594
+ function floydWarshall(G) {
595
+ const verts = Array.from(G.vertices);
596
+ const idx = new Map();
597
+ verts.forEach((v, i) => idx.set(v, i));
598
+ const n = verts.length;
599
+ const D = Array.from({ length: n }, () => new Array(n).fill(Infinity));
600
+ for (let i = 0; i < n; i++)
601
+ D[i][i] = 0;
602
+ for (const e of G.edges) {
603
+ const i = idx.get(e.from);
604
+ const j = idx.get(e.to);
605
+ if (i === undefined || j === undefined)
606
+ continue;
607
+ const w = e.weight ?? 1;
608
+ const row = D[i];
609
+ if (w < (row[j] ?? Infinity))
610
+ row[j] = w;
611
+ if (!G.directed) {
612
+ const rowJ = D[j];
613
+ if (w < (rowJ[i] ?? Infinity))
614
+ rowJ[i] = w;
615
+ }
616
+ }
617
+ for (let k = 0; k < n; k++) {
618
+ const Dk = D[k];
619
+ for (let i = 0; i < n; i++) {
620
+ const Di = D[i];
621
+ const dik = Di[k] ?? Infinity;
622
+ if (dik === Infinity)
623
+ continue;
624
+ for (let j = 0; j < n; j++) {
625
+ const cand = dik + (Dk[j] ?? Infinity);
626
+ if (cand < (Di[j] ?? Infinity))
627
+ Di[j] = cand;
628
+ }
629
+ }
630
+ }
631
+ const out = new Map();
632
+ for (let i = 0; i < n; i++) {
633
+ const row = new Map();
634
+ const vi = verts[i];
635
+ for (let j = 0; j < n; j++) {
636
+ const vj = verts[j];
637
+ row.set(vj, D[i][j] ?? Infinity);
638
+ }
639
+ out.set(vi, row);
640
+ }
641
+ return out;
642
+ }
643
+ // ------------------------------------------------------------
644
+ // Disjoint-Set Union (Union-Find) para MST
645
+ // ------------------------------------------------------------
646
+ class DSU {
647
+ parent = new Map();
648
+ rank = new Map();
649
+ add(v) {
650
+ if (!this.parent.has(v)) {
651
+ this.parent.set(v, v);
652
+ this.rank.set(v, 0);
653
+ }
654
+ }
655
+ find(v) {
656
+ let cur = v;
657
+ while (this.parent.get(cur) !== cur) {
658
+ const p = this.parent.get(cur);
659
+ const gp = this.parent.get(p);
660
+ this.parent.set(cur, gp);
661
+ cur = gp;
662
+ }
663
+ return cur;
664
+ }
665
+ union(a, b) {
666
+ const ra = this.find(a);
667
+ const rb = this.find(b);
668
+ if (ra === rb)
669
+ return false;
670
+ const rka = this.rank.get(ra) ?? 0;
671
+ const rkb = this.rank.get(rb) ?? 0;
672
+ if (rka < rkb)
673
+ this.parent.set(ra, rb);
674
+ else if (rka > rkb)
675
+ this.parent.set(rb, ra);
676
+ else {
677
+ this.parent.set(rb, ra);
678
+ this.rank.set(ra, rka + 1);
679
+ }
680
+ return true;
681
+ }
682
+ }
683
+ // ------------------------------------------------------------
684
+ // MST
685
+ // ------------------------------------------------------------
686
+ function kruskal(G) {
687
+ if (G.directed) {
688
+ throw new Error('kruskal: requiere grafo no dirigido');
689
+ }
690
+ const dsu = new DSU();
691
+ for (const v of G.vertices)
692
+ dsu.add(v);
693
+ const sorted = G.edges
694
+ .map((e) => ({ from: e.from, to: e.to, weight: e.weight ?? 1 }))
695
+ .sort((a, b) => a.weight - b.weight);
696
+ const result = [];
697
+ let total = 0;
698
+ for (const e of sorted) {
699
+ if (dsu.union(e.from, e.to)) {
700
+ result.push(e);
701
+ total += e.weight;
702
+ }
703
+ }
704
+ return { edges: result, totalWeight: total };
705
+ }
706
+ function prim(G, start) {
707
+ if (G.directed) {
708
+ throw new Error('prim: requiere grafo no dirigido');
709
+ }
710
+ if (G.vertices.size === 0)
711
+ return { edges: [], totalWeight: 0 };
712
+ const root = start !== undefined && G.vertices.has(start) ? start : G.vertices.values().next().value;
713
+ const adj = buildAdjacency(G);
714
+ const inTree = new Set([root]);
715
+ // Heap de aristas candidatas [peso, from, to].
716
+ const heap = new MinHeap();
717
+ for (const { to, weight } of adj.get(root) ?? []) {
718
+ heap.push([weight, { from: root, to }]);
719
+ }
720
+ const result = [];
721
+ let total = 0;
722
+ while (heap.size > 0 && inTree.size < G.vertices.size) {
723
+ const top = heap.pop();
724
+ if (!top)
725
+ break;
726
+ const [w, e] = top;
727
+ if (inTree.has(e.to))
728
+ continue;
729
+ inTree.add(e.to);
730
+ result.push({ from: e.from, to: e.to, weight: w });
731
+ total += w;
732
+ for (const { to, weight } of adj.get(e.to) ?? []) {
733
+ if (!inTree.has(to))
734
+ heap.push([weight, { from: e.to, to }]);
735
+ }
736
+ }
737
+ return { edges: result, totalWeight: total };
738
+ }
739
+ // ------------------------------------------------------------
740
+ // Bipartite matching
741
+ // ------------------------------------------------------------
742
+ // Empareja izquierda con derecha vía DFS-aumento (algoritmo de Kuhn).
743
+ function bipartiteMaximumMatching(G, leftPartition) {
744
+ const adj = buildAdjacency(G);
745
+ const matchR = new Map(); // right → left
746
+ const tryKuhn = (u, visited) => {
747
+ const nbrs = adj.get(u) ?? [];
748
+ for (const { to: w } of nbrs) {
749
+ if (leftPartition.has(w))
750
+ continue;
751
+ if (visited.has(w))
752
+ continue;
753
+ visited.add(w);
754
+ const matched = matchR.get(w);
755
+ if (matched === undefined || tryKuhn(matched, visited)) {
756
+ matchR.set(w, u);
757
+ return true;
758
+ }
759
+ }
760
+ return false;
761
+ };
762
+ for (const u of leftPartition) {
763
+ if (!G.vertices.has(u))
764
+ continue;
765
+ tryKuhn(u, new Set());
766
+ }
767
+ const out = [];
768
+ for (const [r, l] of matchR)
769
+ out.push({ left: l, right: r });
770
+ return out;
771
+ }
772
+ // Hopcroft-Karp con BFS por niveles + DFS de aumento.
773
+ function hopcroftKarp(G, leftPartition) {
774
+ const adj = buildAdjacency(G);
775
+ const pairL = new Map();
776
+ const pairR = new Map();
777
+ const distL = new Map();
778
+ const left = [];
779
+ for (const v of leftPartition) {
780
+ if (G.vertices.has(v)) {
781
+ left.push(v);
782
+ pairL.set(v, null);
783
+ }
784
+ }
785
+ for (const v of G.vertices) {
786
+ if (!leftPartition.has(v))
787
+ pairR.set(v, null);
788
+ }
789
+ const INF = Number.POSITIVE_INFINITY;
790
+ const bfsLayers = () => {
791
+ const queue = [];
792
+ for (const u of left) {
793
+ if (pairL.get(u) === null) {
794
+ distL.set(u, 0);
795
+ queue.push(u);
796
+ }
797
+ else {
798
+ distL.set(u, INF);
799
+ }
800
+ }
801
+ let found = false;
802
+ let head = 0;
803
+ while (head < queue.length) {
804
+ const u = queue[head++];
805
+ const du = distL.get(u) ?? INF;
806
+ const nbrs = adj.get(u) ?? [];
807
+ for (const { to: v } of nbrs) {
808
+ if (leftPartition.has(v))
809
+ continue;
810
+ const pv = pairR.get(v);
811
+ if (pv === null || pv === undefined) {
812
+ found = true;
813
+ }
814
+ else {
815
+ if ((distL.get(pv) ?? INF) === INF) {
816
+ distL.set(pv, du + 1);
817
+ queue.push(pv);
818
+ }
819
+ }
820
+ }
821
+ }
822
+ return found;
823
+ };
824
+ const dfsAugment = (u) => {
825
+ const nbrs = adj.get(u) ?? [];
826
+ for (const { to: v } of nbrs) {
827
+ if (leftPartition.has(v))
828
+ continue;
829
+ const pv = pairR.get(v) ?? null;
830
+ const expected = (distL.get(u) ?? INF) + 1;
831
+ const dpv = pv === null ? INF : (distL.get(pv) ?? INF);
832
+ if (pv === null || (dpv === expected && dfsAugment(pv))) {
833
+ pairL.set(u, v);
834
+ pairR.set(v, u);
835
+ return true;
836
+ }
837
+ }
838
+ distL.set(u, INF);
839
+ return false;
840
+ };
841
+ while (bfsLayers()) {
842
+ for (const u of left) {
843
+ if (pairL.get(u) === null)
844
+ dfsAugment(u);
845
+ }
846
+ }
847
+ const out = [];
848
+ for (const u of left) {
849
+ const v = pairL.get(u);
850
+ if (v !== null && v !== undefined)
851
+ out.push({ left: u, right: v });
852
+ }
853
+ return out;
854
+ }
855
+ // ------------------------------------------------------------
856
+ // Coloreo
857
+ // ------------------------------------------------------------
858
+ // Greedy: ordena por grado descendente y asigna el primer color disponible.
859
+ function greedyColoring(G) {
860
+ const order = Array.from(G.vertices).sort((a, b) => degreeUndirected(G, b) - degreeUndirected(G, a));
861
+ const color = new Map();
862
+ for (const v of order) {
863
+ const used = new Set();
864
+ for (const n of neighbors(G, v)) {
865
+ const c = color.get(n);
866
+ if (c !== undefined)
867
+ used.add(c);
868
+ }
869
+ let c = 0;
870
+ while (used.has(c))
871
+ c++;
872
+ color.set(v, c);
873
+ }
874
+ return color;
875
+ }
876
+ // Número cromático por backtracking con poda (intenta k = 1, 2, ...).
877
+ function chromaticNumber(G) {
878
+ const verts = Array.from(G.vertices);
879
+ if (verts.length === 0)
880
+ return 0;
881
+ // Si hay aristas, al menos 2.
882
+ const adj = new Map();
883
+ for (const v of verts)
884
+ adj.set(v, new Set());
885
+ for (const e of G.edges) {
886
+ if (e.from === e.to)
887
+ continue;
888
+ adj.get(e.from)?.add(e.to);
889
+ adj.get(e.to)?.add(e.from);
890
+ }
891
+ const canColor = (k) => {
892
+ const color = new Array(verts.length).fill(-1);
893
+ const idxOf = new Map();
894
+ verts.forEach((v, i) => idxOf.set(v, i));
895
+ const dfs = (i) => {
896
+ if (i === verts.length)
897
+ return true;
898
+ const v = verts[i];
899
+ const used = new Set();
900
+ for (const nb of adj.get(v) ?? []) {
901
+ const ci = color[idxOf.get(nb)];
902
+ if (ci !== undefined && ci >= 0)
903
+ used.add(ci);
904
+ }
905
+ for (let c = 0; c < k; c++) {
906
+ if (used.has(c))
907
+ continue;
908
+ color[i] = c;
909
+ if (dfs(i + 1))
910
+ return true;
911
+ color[i] = -1;
912
+ }
913
+ return false;
914
+ };
915
+ return dfs(0);
916
+ };
917
+ for (let k = 1; k <= verts.length; k++) {
918
+ if (canColor(k))
919
+ return k;
920
+ }
921
+ return verts.length;
922
+ }
923
+ // ------------------------------------------------------------
924
+ // Isomorfismo (grafos pequeños)
925
+ // ------------------------------------------------------------
926
+ // Heurística de refinamiento de invariantes (1-WL liviano): para cada
927
+ // vértice arma una firma (grado, multiset de grados de vecinos) y permite
928
+ // rechazar rápidamente. Si las firmas globales no coinciden, no iso.
929
+ function vertexSignatures(G) {
930
+ const sig = new Map();
931
+ for (const v of G.vertices) {
932
+ const nbDegrees = neighbors(G, v).map((n) => degreeUndirected(G, n));
933
+ nbDegrees.sort((a, b) => a - b);
934
+ sig.set(v, `${degreeUndirected(G, v)}|${nbDegrees.join(',')}`);
935
+ }
936
+ return sig;
937
+ }
938
+ function signatureMultiset(sigs) {
939
+ const arr = Array.from(sigs.values());
940
+ arr.sort();
941
+ return arr.join('||');
942
+ }
943
+ function areIsomorphic(g1, g2) {
944
+ return findIsomorphism(g1, g2) !== null;
945
+ }
946
+ function findIsomorphism(g1, g2) {
947
+ if (g1.directed !== g2.directed)
948
+ return null;
949
+ if (g1.vertices.size !== g2.vertices.size)
950
+ return null;
951
+ if (g1.edges.length !== g2.edges.length)
952
+ return null;
953
+ // Comparar secuencia de grados.
954
+ const deg1 = Array.from(g1.vertices)
955
+ .map((v) => degreeUndirected(g1, v))
956
+ .sort((a, b) => a - b);
957
+ const deg2 = Array.from(g2.vertices)
958
+ .map((v) => degreeUndirected(g2, v))
959
+ .sort((a, b) => a - b);
960
+ if (deg1.length !== deg2.length || deg1.some((d, i) => d !== deg2[i]))
961
+ return null;
962
+ // Comparar firmas vecinales.
963
+ const sig1 = vertexSignatures(g1);
964
+ const sig2 = vertexSignatures(g2);
965
+ if (signatureMultiset(sig1) !== signatureMultiset(sig2))
966
+ return null;
967
+ const verts1 = Array.from(g1.vertices);
968
+ const verts2 = Array.from(g2.vertices);
969
+ // Adyacencia como set de pares para chequeo rápido.
970
+ const adj1 = new Map();
971
+ for (const v of verts1)
972
+ adj1.set(v, new Set());
973
+ for (const e of g1.edges) {
974
+ adj1.get(e.from)?.add(e.to);
975
+ if (!g1.directed)
976
+ adj1.get(e.to)?.add(e.from);
977
+ }
978
+ const adj2 = new Map();
979
+ for (const v of verts2)
980
+ adj2.set(v, new Set());
981
+ for (const e of g2.edges) {
982
+ adj2.get(e.from)?.add(e.to);
983
+ if (!g2.directed)
984
+ adj2.get(e.to)?.add(e.from);
985
+ }
986
+ // Backtracking: emparejar verts1[i] con un v2 compatible.
987
+ const mapping = new Map();
988
+ const used = new Set();
989
+ // Candidatos por firma para cada vértice de g1.
990
+ const candidates = new Map();
991
+ for (const v of verts1) {
992
+ const cand = [];
993
+ const s = sig1.get(v);
994
+ for (const w of verts2) {
995
+ if (sig2.get(w) === s)
996
+ cand.push(w);
997
+ }
998
+ candidates.set(v, cand);
999
+ }
1000
+ // Ordenar verts1 por número de candidatos (variable más restrictiva primero).
1001
+ const order = verts1.slice().sort((a, b) => {
1002
+ return (candidates.get(a)?.length ?? 0) - (candidates.get(b)?.length ?? 0);
1003
+ });
1004
+ const compatible = (u, w) => {
1005
+ // Para cada vecino previamente mapeado de u en g1, el correspondiente
1006
+ // mapeo en g2 debe ser vecino de w.
1007
+ for (const [uPrev, wPrev] of mapping) {
1008
+ const uAdj = adj1.get(u)?.has(uPrev) ?? false;
1009
+ const wAdj = adj2.get(w)?.has(wPrev) ?? false;
1010
+ if (uAdj !== wAdj)
1011
+ return false;
1012
+ if (g1.directed) {
1013
+ const uAdjRev = adj1.get(uPrev)?.has(u) ?? false;
1014
+ const wAdjRev = adj2.get(wPrev)?.has(w) ?? false;
1015
+ if (uAdjRev !== wAdjRev)
1016
+ return false;
1017
+ }
1018
+ }
1019
+ return true;
1020
+ };
1021
+ const backtrack = (i) => {
1022
+ if (i === order.length)
1023
+ return true;
1024
+ const u = order[i];
1025
+ for (const w of candidates.get(u) ?? []) {
1026
+ if (used.has(w))
1027
+ continue;
1028
+ if (!compatible(u, w))
1029
+ continue;
1030
+ mapping.set(u, w);
1031
+ used.add(w);
1032
+ if (backtrack(i + 1))
1033
+ return true;
1034
+ mapping.delete(u);
1035
+ used.delete(w);
1036
+ }
1037
+ return false;
1038
+ };
1039
+ if (backtrack(0))
1040
+ return mapping;
1041
+ return null;
1042
+ }
1043
+ //# sourceMappingURL=index.js.map