okstra 0.130.4 → 0.131.1

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 (365) hide show
  1. package/README.md +0 -1
  2. package/docs/architecture.md +2 -2
  3. package/docs/cli.md +1 -1
  4. package/docs/for-ai/README.md +0 -2
  5. package/docs/for-ai/skills/okstra-run.md +13 -2
  6. package/docs/for-ai/skills/okstra-setup.md +4 -1
  7. package/docs/project-structure-overview.md +5 -4
  8. package/docs/task-process/implementation-planning.md +13 -0
  9. package/docs/task-process/implementation.md +17 -2
  10. package/package.json +1 -1
  11. package/runtime/BUILD.json +2 -2
  12. package/runtime/agents/workers/report-writer-worker.md +7 -0
  13. package/runtime/bin/lib/okstra/usage.sh +4 -4
  14. package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
  15. package/runtime/prompts/lead/plan-body-verification.md +26 -5
  16. package/runtime/prompts/lead/report-writer.md +6 -2
  17. package/runtime/prompts/profiles/_common-contract.md +2 -1
  18. package/runtime/prompts/profiles/_implementation-deliverable.md +6 -1
  19. package/runtime/prompts/profiles/_implementation-executor.md +2 -2
  20. package/runtime/prompts/profiles/_implementation-verifier.md +33 -10
  21. package/runtime/prompts/profiles/final-verification.md +21 -6
  22. package/runtime/prompts/profiles/implementation-planning.md +16 -4
  23. package/runtime/python/okstra_ctl/codex_dispatch.py +31 -0
  24. package/runtime/python/okstra_ctl/conformance.py +49 -11
  25. package/runtime/python/okstra_ctl/report_finalize.py +52 -1
  26. package/runtime/python/okstra_ctl/run.py +15 -3
  27. package/runtime/python/okstra_ctl/worker_prompt_contract.py +14 -6
  28. package/runtime/python/okstra_ctl/worker_prompt_policy.py +19 -1
  29. package/runtime/python/okstra_vendor/__init__.py +0 -44
  30. package/runtime/schemas/final-report-v1.0.schema.json +99 -5
  31. package/runtime/skills/okstra-run/SKILL.md +11 -4
  32. package/runtime/skills/okstra-setup/SKILL.md +3 -2
  33. package/runtime/skills/okstra-setup/references/project-config.md +16 -7
  34. package/runtime/templates/reports/final-report.template.md +15 -9
  35. package/runtime/templates/reports/i18n/en.json +1 -0
  36. package/runtime/templates/reports/i18n/ko.json +1 -0
  37. package/runtime/validators/lib/fixtures.sh +6 -0
  38. package/runtime/validators/validate-run.py +2019 -96
  39. package/src/cli-registry.mjs +0 -7
  40. package/src/commands/lifecycle/doctor.mjs +0 -9
  41. package/src/lib/skill-catalog.mjs +0 -1
  42. package/docs/for-ai/skills/okstra-graphify.md +0 -64
  43. package/runtime/python/okstra_ctl/graphify_cmd.py +0 -225
  44. package/runtime/python/okstra_vendor/graphify/.vendored-version +0 -1
  45. package/runtime/python/okstra_vendor/graphify/__init__.py +0 -28
  46. package/runtime/python/okstra_vendor/graphify/__main__.py +0 -1371
  47. package/runtime/python/okstra_vendor/graphify/analyze.py +0 -540
  48. package/runtime/python/okstra_vendor/graphify/benchmark.py +0 -129
  49. package/runtime/python/okstra_vendor/graphify/build.py +0 -107
  50. package/runtime/python/okstra_vendor/graphify/cache.py +0 -169
  51. package/runtime/python/okstra_vendor/graphify/cluster.py +0 -137
  52. package/runtime/python/okstra_vendor/graphify/detect.py +0 -510
  53. package/runtime/python/okstra_vendor/graphify/export.py +0 -1014
  54. package/runtime/python/okstra_vendor/graphify/extract.py +0 -3277
  55. package/runtime/python/okstra_vendor/graphify/hooks.py +0 -220
  56. package/runtime/python/okstra_vendor/graphify/ingest.py +0 -297
  57. package/runtime/python/okstra_vendor/graphify/manifest.py +0 -4
  58. package/runtime/python/okstra_vendor/graphify/report.py +0 -175
  59. package/runtime/python/okstra_vendor/graphify/security.py +0 -203
  60. package/runtime/python/okstra_vendor/graphify/serve.py +0 -373
  61. package/runtime/python/okstra_vendor/graphify/skill-aider.md +0 -1184
  62. package/runtime/python/okstra_vendor/graphify/skill-claw.md +0 -1184
  63. package/runtime/python/okstra_vendor/graphify/skill-codex.md +0 -1242
  64. package/runtime/python/okstra_vendor/graphify/skill-copilot.md +0 -1268
  65. package/runtime/python/okstra_vendor/graphify/skill-droid.md +0 -1239
  66. package/runtime/python/okstra_vendor/graphify/skill-kiro.md +0 -1183
  67. package/runtime/python/okstra_vendor/graphify/skill-opencode.md +0 -1238
  68. package/runtime/python/okstra_vendor/graphify/skill-trae.md +0 -1208
  69. package/runtime/python/okstra_vendor/graphify/skill-vscode.md +0 -253
  70. package/runtime/python/okstra_vendor/graphify/skill-windows.md +0 -1245
  71. package/runtime/python/okstra_vendor/graphify/skill.md +0 -1319
  72. package/runtime/python/okstra_vendor/graphify/transcribe.py +0 -182
  73. package/runtime/python/okstra_vendor/graphify/validate.py +0 -72
  74. package/runtime/python/okstra_vendor/graphify/watch.py +0 -188
  75. package/runtime/python/okstra_vendor/graphify/wiki.py +0 -214
  76. package/runtime/python/okstra_vendor/networkx/__init__.py +0 -62
  77. package/runtime/python/okstra_vendor/networkx/algorithms/__init__.py +0 -134
  78. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/__init__.py +0 -26
  79. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clique.py +0 -259
  80. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clustering_coefficient.py +0 -71
  81. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/connectivity.py +0 -412
  82. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/density.py +0 -396
  83. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/distance_measures.py +0 -150
  84. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/dominating_set.py +0 -149
  85. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/kcomponents.py +0 -369
  86. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/matching.py +0 -44
  87. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/maxcut.py +0 -143
  88. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/ramsey.py +0 -53
  89. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/steinertree.py +0 -265
  90. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/traveling_salesman.py +0 -1508
  91. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/treewidth.py +0 -255
  92. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/vertex_cover.py +0 -83
  93. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/__init__.py +0 -5
  94. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/connectivity.py +0 -122
  95. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/correlation.py +0 -302
  96. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/mixing.py +0 -255
  97. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/neighbor_degree.py +0 -160
  98. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/pairs.py +0 -127
  99. package/runtime/python/okstra_vendor/networkx/algorithms/asteroidal.py +0 -164
  100. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/__init__.py +0 -88
  101. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/basic.py +0 -322
  102. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/centrality.py +0 -290
  103. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/cluster.py +0 -289
  104. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/covering.py +0 -57
  105. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/edgelist.py +0 -360
  106. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/extendability.py +0 -105
  107. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/generators.py +0 -603
  108. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/link_analysis.py +0 -316
  109. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matching.py +0 -590
  110. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matrix.py +0 -232
  111. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/projection.py +0 -526
  112. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/redundancy.py +0 -112
  113. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/spectral.py +0 -69
  114. package/runtime/python/okstra_vendor/networkx/algorithms/boundary.py +0 -168
  115. package/runtime/python/okstra_vendor/networkx/algorithms/bridges.py +0 -205
  116. package/runtime/python/okstra_vendor/networkx/algorithms/broadcasting.py +0 -164
  117. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/__init__.py +0 -20
  118. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness.py +0 -591
  119. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness_subset.py +0 -236
  120. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/closeness.py +0 -282
  121. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness.py +0 -364
  122. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness_subset.py +0 -227
  123. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_closeness.py +0 -96
  124. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/degree_alg.py +0 -150
  125. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/dispersion.py +0 -107
  126. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/eigenvector.py +0 -357
  127. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/flow_matrix.py +0 -130
  128. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/group.py +0 -787
  129. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/harmonic.py +0 -88
  130. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/katz.py +0 -331
  131. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/laplacian.py +0 -150
  132. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/load.py +0 -200
  133. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/percolation.py +0 -128
  134. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/reaching.py +0 -209
  135. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/second_order.py +0 -141
  136. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/subgraph_alg.py +0 -361
  137. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/trophic.py +0 -181
  138. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/voterank_alg.py +0 -95
  139. package/runtime/python/okstra_vendor/networkx/algorithms/chains.py +0 -172
  140. package/runtime/python/okstra_vendor/networkx/algorithms/chordal.py +0 -443
  141. package/runtime/python/okstra_vendor/networkx/algorithms/clique.py +0 -818
  142. package/runtime/python/okstra_vendor/networkx/algorithms/cluster.py +0 -732
  143. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/__init__.py +0 -4
  144. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/equitable_coloring.py +0 -505
  145. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/greedy_coloring.py +0 -565
  146. package/runtime/python/okstra_vendor/networkx/algorithms/communicability_alg.py +0 -163
  147. package/runtime/python/okstra_vendor/networkx/algorithms/community/__init__.py +0 -28
  148. package/runtime/python/okstra_vendor/networkx/algorithms/community/asyn_fluid.py +0 -153
  149. package/runtime/python/okstra_vendor/networkx/algorithms/community/bipartitions.py +0 -354
  150. package/runtime/python/okstra_vendor/networkx/algorithms/community/centrality.py +0 -171
  151. package/runtime/python/okstra_vendor/networkx/algorithms/community/community_utils.py +0 -30
  152. package/runtime/python/okstra_vendor/networkx/algorithms/community/divisive.py +0 -216
  153. package/runtime/python/okstra_vendor/networkx/algorithms/community/kclique.py +0 -79
  154. package/runtime/python/okstra_vendor/networkx/algorithms/community/label_propagation.py +0 -338
  155. package/runtime/python/okstra_vendor/networkx/algorithms/community/leiden.py +0 -162
  156. package/runtime/python/okstra_vendor/networkx/algorithms/community/local.py +0 -220
  157. package/runtime/python/okstra_vendor/networkx/algorithms/community/louvain.py +0 -384
  158. package/runtime/python/okstra_vendor/networkx/algorithms/community/lukes.py +0 -227
  159. package/runtime/python/okstra_vendor/networkx/algorithms/community/modularity_max.py +0 -452
  160. package/runtime/python/okstra_vendor/networkx/algorithms/community/quality.py +0 -347
  161. package/runtime/python/okstra_vendor/networkx/algorithms/components/__init__.py +0 -6
  162. package/runtime/python/okstra_vendor/networkx/algorithms/components/attracting.py +0 -115
  163. package/runtime/python/okstra_vendor/networkx/algorithms/components/biconnected.py +0 -394
  164. package/runtime/python/okstra_vendor/networkx/algorithms/components/connected.py +0 -282
  165. package/runtime/python/okstra_vendor/networkx/algorithms/components/semiconnected.py +0 -71
  166. package/runtime/python/okstra_vendor/networkx/algorithms/components/strongly_connected.py +0 -359
  167. package/runtime/python/okstra_vendor/networkx/algorithms/components/weakly_connected.py +0 -196
  168. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/__init__.py +0 -11
  169. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/connectivity.py +0 -811
  170. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/cuts.py +0 -616
  171. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/disjoint_paths.py +0 -408
  172. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_augmentation.py +0 -1270
  173. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_kcomponents.py +0 -592
  174. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcomponents.py +0 -220
  175. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcutsets.py +0 -235
  176. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/stoerwagner.py +0 -152
  177. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/utils.py +0 -88
  178. package/runtime/python/okstra_vendor/networkx/algorithms/core.py +0 -588
  179. package/runtime/python/okstra_vendor/networkx/algorithms/covering.py +0 -142
  180. package/runtime/python/okstra_vendor/networkx/algorithms/cuts.py +0 -416
  181. package/runtime/python/okstra_vendor/networkx/algorithms/cycles.py +0 -1234
  182. package/runtime/python/okstra_vendor/networkx/algorithms/d_separation.py +0 -677
  183. package/runtime/python/okstra_vendor/networkx/algorithms/dag.py +0 -1392
  184. package/runtime/python/okstra_vendor/networkx/algorithms/distance_measures.py +0 -1095
  185. package/runtime/python/okstra_vendor/networkx/algorithms/distance_regular.py +0 -272
  186. package/runtime/python/okstra_vendor/networkx/algorithms/dominance.py +0 -142
  187. package/runtime/python/okstra_vendor/networkx/algorithms/dominating.py +0 -268
  188. package/runtime/python/okstra_vendor/networkx/algorithms/efficiency_measures.py +0 -167
  189. package/runtime/python/okstra_vendor/networkx/algorithms/euler.py +0 -470
  190. package/runtime/python/okstra_vendor/networkx/algorithms/flow/__init__.py +0 -11
  191. package/runtime/python/okstra_vendor/networkx/algorithms/flow/boykovkolmogorov.py +0 -370
  192. package/runtime/python/okstra_vendor/networkx/algorithms/flow/capacityscaling.py +0 -407
  193. package/runtime/python/okstra_vendor/networkx/algorithms/flow/dinitz_alg.py +0 -238
  194. package/runtime/python/okstra_vendor/networkx/algorithms/flow/edmondskarp.py +0 -241
  195. package/runtime/python/okstra_vendor/networkx/algorithms/flow/gomory_hu.py +0 -178
  196. package/runtime/python/okstra_vendor/networkx/algorithms/flow/maxflow.py +0 -611
  197. package/runtime/python/okstra_vendor/networkx/algorithms/flow/mincost.py +0 -356
  198. package/runtime/python/okstra_vendor/networkx/algorithms/flow/networksimplex.py +0 -662
  199. package/runtime/python/okstra_vendor/networkx/algorithms/flow/preflowpush.py +0 -425
  200. package/runtime/python/okstra_vendor/networkx/algorithms/flow/shortestaugmentingpath.py +0 -300
  201. package/runtime/python/okstra_vendor/networkx/algorithms/flow/utils.py +0 -194
  202. package/runtime/python/okstra_vendor/networkx/algorithms/graph_hashing.py +0 -435
  203. package/runtime/python/okstra_vendor/networkx/algorithms/graphical.py +0 -483
  204. package/runtime/python/okstra_vendor/networkx/algorithms/hierarchy.py +0 -57
  205. package/runtime/python/okstra_vendor/networkx/algorithms/hybrid.py +0 -196
  206. package/runtime/python/okstra_vendor/networkx/algorithms/isolate.py +0 -107
  207. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/__init__.py +0 -7
  208. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/ismags.py +0 -1306
  209. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorph.py +0 -336
  210. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorphvf2.py +0 -1262
  211. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/matchhelpers.py +0 -352
  212. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/temporalisomorphvf2.py +0 -308
  213. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tree_isomorphism.py +0 -264
  214. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2pp.py +0 -1102
  215. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2userfunc.py +0 -192
  216. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/__init__.py +0 -2
  217. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/hits_alg.py +0 -337
  218. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/pagerank_alg.py +0 -498
  219. package/runtime/python/okstra_vendor/networkx/algorithms/link_prediction.py +0 -687
  220. package/runtime/python/okstra_vendor/networkx/algorithms/lowest_common_ancestors.py +0 -280
  221. package/runtime/python/okstra_vendor/networkx/algorithms/matching.py +0 -1148
  222. package/runtime/python/okstra_vendor/networkx/algorithms/minors/__init__.py +0 -27
  223. package/runtime/python/okstra_vendor/networkx/algorithms/minors/contraction.py +0 -738
  224. package/runtime/python/okstra_vendor/networkx/algorithms/mis.py +0 -78
  225. package/runtime/python/okstra_vendor/networkx/algorithms/moral.py +0 -59
  226. package/runtime/python/okstra_vendor/networkx/algorithms/node_classification.py +0 -219
  227. package/runtime/python/okstra_vendor/networkx/algorithms/non_randomness.py +0 -155
  228. package/runtime/python/okstra_vendor/networkx/algorithms/operators/__init__.py +0 -4
  229. package/runtime/python/okstra_vendor/networkx/algorithms/operators/all.py +0 -324
  230. package/runtime/python/okstra_vendor/networkx/algorithms/operators/binary.py +0 -468
  231. package/runtime/python/okstra_vendor/networkx/algorithms/operators/product.py +0 -633
  232. package/runtime/python/okstra_vendor/networkx/algorithms/operators/unary.py +0 -77
  233. package/runtime/python/okstra_vendor/networkx/algorithms/perfect_graph.py +0 -73
  234. package/runtime/python/okstra_vendor/networkx/algorithms/planar_drawing.py +0 -464
  235. package/runtime/python/okstra_vendor/networkx/algorithms/planarity.py +0 -1463
  236. package/runtime/python/okstra_vendor/networkx/algorithms/polynomials.py +0 -306
  237. package/runtime/python/okstra_vendor/networkx/algorithms/reciprocity.py +0 -98
  238. package/runtime/python/okstra_vendor/networkx/algorithms/regular.py +0 -167
  239. package/runtime/python/okstra_vendor/networkx/algorithms/richclub.py +0 -138
  240. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/__init__.py +0 -5
  241. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/astar.py +0 -239
  242. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/dense.py +0 -264
  243. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/generic.py +0 -716
  244. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/unweighted.py +0 -625
  245. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/weighted.py +0 -2542
  246. package/runtime/python/okstra_vendor/networkx/algorithms/similarity.py +0 -2107
  247. package/runtime/python/okstra_vendor/networkx/algorithms/simple_paths.py +0 -966
  248. package/runtime/python/okstra_vendor/networkx/algorithms/smallworld.py +0 -404
  249. package/runtime/python/okstra_vendor/networkx/algorithms/smetric.py +0 -30
  250. package/runtime/python/okstra_vendor/networkx/algorithms/sparsifiers.py +0 -296
  251. package/runtime/python/okstra_vendor/networkx/algorithms/structuralholes.py +0 -374
  252. package/runtime/python/okstra_vendor/networkx/algorithms/summarization.py +0 -564
  253. package/runtime/python/okstra_vendor/networkx/algorithms/swap.py +0 -406
  254. package/runtime/python/okstra_vendor/networkx/algorithms/threshold.py +0 -981
  255. package/runtime/python/okstra_vendor/networkx/algorithms/time_dependent.py +0 -142
  256. package/runtime/python/okstra_vendor/networkx/algorithms/tournament.py +0 -406
  257. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/__init__.py +0 -5
  258. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/beamsearch.py +0 -90
  259. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/breadth_first_search.py +0 -576
  260. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/depth_first_search.py +0 -529
  261. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgebfs.py +0 -185
  262. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgedfs.py +0 -182
  263. package/runtime/python/okstra_vendor/networkx/algorithms/tree/__init__.py +0 -7
  264. package/runtime/python/okstra_vendor/networkx/algorithms/tree/branchings.py +0 -1042
  265. package/runtime/python/okstra_vendor/networkx/algorithms/tree/coding.py +0 -413
  266. package/runtime/python/okstra_vendor/networkx/algorithms/tree/decomposition.py +0 -88
  267. package/runtime/python/okstra_vendor/networkx/algorithms/tree/distance_measures.py +0 -219
  268. package/runtime/python/okstra_vendor/networkx/algorithms/tree/mst.py +0 -1281
  269. package/runtime/python/okstra_vendor/networkx/algorithms/tree/operations.py +0 -106
  270. package/runtime/python/okstra_vendor/networkx/algorithms/tree/recognition.py +0 -273
  271. package/runtime/python/okstra_vendor/networkx/algorithms/triads.py +0 -500
  272. package/runtime/python/okstra_vendor/networkx/algorithms/vitality.py +0 -76
  273. package/runtime/python/okstra_vendor/networkx/algorithms/voronoi.py +0 -86
  274. package/runtime/python/okstra_vendor/networkx/algorithms/walks.py +0 -77
  275. package/runtime/python/okstra_vendor/networkx/algorithms/wiener.py +0 -278
  276. package/runtime/python/okstra_vendor/networkx/classes/__init__.py +0 -13
  277. package/runtime/python/okstra_vendor/networkx/classes/coreviews.py +0 -435
  278. package/runtime/python/okstra_vendor/networkx/classes/digraph.py +0 -1363
  279. package/runtime/python/okstra_vendor/networkx/classes/filters.py +0 -95
  280. package/runtime/python/okstra_vendor/networkx/classes/function.py +0 -1549
  281. package/runtime/python/okstra_vendor/networkx/classes/graph.py +0 -2082
  282. package/runtime/python/okstra_vendor/networkx/classes/graphviews.py +0 -269
  283. package/runtime/python/okstra_vendor/networkx/classes/multidigraph.py +0 -977
  284. package/runtime/python/okstra_vendor/networkx/classes/multigraph.py +0 -1294
  285. package/runtime/python/okstra_vendor/networkx/classes/reportviews.py +0 -1447
  286. package/runtime/python/okstra_vendor/networkx/convert.py +0 -502
  287. package/runtime/python/okstra_vendor/networkx/convert_matrix.py +0 -1314
  288. package/runtime/python/okstra_vendor/networkx/drawing/__init__.py +0 -7
  289. package/runtime/python/okstra_vendor/networkx/drawing/layout.py +0 -2036
  290. package/runtime/python/okstra_vendor/networkx/drawing/nx_agraph.py +0 -470
  291. package/runtime/python/okstra_vendor/networkx/drawing/nx_latex.py +0 -570
  292. package/runtime/python/okstra_vendor/networkx/drawing/nx_pydot.py +0 -361
  293. package/runtime/python/okstra_vendor/networkx/drawing/nx_pylab.py +0 -2978
  294. package/runtime/python/okstra_vendor/networkx/exception.py +0 -131
  295. package/runtime/python/okstra_vendor/networkx/generators/__init__.py +0 -34
  296. package/runtime/python/okstra_vendor/networkx/generators/atlas.dat.gz +0 -0
  297. package/runtime/python/okstra_vendor/networkx/generators/atlas.py +0 -227
  298. package/runtime/python/okstra_vendor/networkx/generators/classic.py +0 -1091
  299. package/runtime/python/okstra_vendor/networkx/generators/cographs.py +0 -68
  300. package/runtime/python/okstra_vendor/networkx/generators/community.py +0 -1070
  301. package/runtime/python/okstra_vendor/networkx/generators/degree_seq.py +0 -886
  302. package/runtime/python/okstra_vendor/networkx/generators/directed.py +0 -572
  303. package/runtime/python/okstra_vendor/networkx/generators/duplication.py +0 -174
  304. package/runtime/python/okstra_vendor/networkx/generators/ego.py +0 -66
  305. package/runtime/python/okstra_vendor/networkx/generators/expanders.py +0 -499
  306. package/runtime/python/okstra_vendor/networkx/generators/geometric.py +0 -1037
  307. package/runtime/python/okstra_vendor/networkx/generators/harary_graph.py +0 -163
  308. package/runtime/python/okstra_vendor/networkx/generators/internet_as_graphs.py +0 -443
  309. package/runtime/python/okstra_vendor/networkx/generators/intersection.py +0 -125
  310. package/runtime/python/okstra_vendor/networkx/generators/interval_graph.py +0 -70
  311. package/runtime/python/okstra_vendor/networkx/generators/joint_degree_seq.py +0 -664
  312. package/runtime/python/okstra_vendor/networkx/generators/lattice.py +0 -405
  313. package/runtime/python/okstra_vendor/networkx/generators/line.py +0 -501
  314. package/runtime/python/okstra_vendor/networkx/generators/mycielski.py +0 -110
  315. package/runtime/python/okstra_vendor/networkx/generators/nonisomorphic_trees.py +0 -259
  316. package/runtime/python/okstra_vendor/networkx/generators/random_clustered.py +0 -117
  317. package/runtime/python/okstra_vendor/networkx/generators/random_graphs.py +0 -1416
  318. package/runtime/python/okstra_vendor/networkx/generators/small.py +0 -1070
  319. package/runtime/python/okstra_vendor/networkx/generators/social.py +0 -554
  320. package/runtime/python/okstra_vendor/networkx/generators/spectral_graph_forge.py +0 -120
  321. package/runtime/python/okstra_vendor/networkx/generators/stochastic.py +0 -54
  322. package/runtime/python/okstra_vendor/networkx/generators/sudoku.py +0 -131
  323. package/runtime/python/okstra_vendor/networkx/generators/time_series.py +0 -74
  324. package/runtime/python/okstra_vendor/networkx/generators/trees.py +0 -1070
  325. package/runtime/python/okstra_vendor/networkx/generators/triads.py +0 -94
  326. package/runtime/python/okstra_vendor/networkx/lazy_imports.py +0 -188
  327. package/runtime/python/okstra_vendor/networkx/linalg/__init__.py +0 -13
  328. package/runtime/python/okstra_vendor/networkx/linalg/algebraicconnectivity.py +0 -650
  329. package/runtime/python/okstra_vendor/networkx/linalg/attrmatrix.py +0 -466
  330. package/runtime/python/okstra_vendor/networkx/linalg/bethehessianmatrix.py +0 -77
  331. package/runtime/python/okstra_vendor/networkx/linalg/graphmatrix.py +0 -168
  332. package/runtime/python/okstra_vendor/networkx/linalg/laplacianmatrix.py +0 -512
  333. package/runtime/python/okstra_vendor/networkx/linalg/modularitymatrix.py +0 -166
  334. package/runtime/python/okstra_vendor/networkx/linalg/spectrum.py +0 -186
  335. package/runtime/python/okstra_vendor/networkx/readwrite/__init__.py +0 -17
  336. package/runtime/python/okstra_vendor/networkx/readwrite/adjlist.py +0 -330
  337. package/runtime/python/okstra_vendor/networkx/readwrite/edgelist.py +0 -489
  338. package/runtime/python/okstra_vendor/networkx/readwrite/gexf.py +0 -1084
  339. package/runtime/python/okstra_vendor/networkx/readwrite/gml.py +0 -879
  340. package/runtime/python/okstra_vendor/networkx/readwrite/graph6.py +0 -427
  341. package/runtime/python/okstra_vendor/networkx/readwrite/graphml.py +0 -1053
  342. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/__init__.py +0 -19
  343. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/adjacency.py +0 -156
  344. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/cytoscape.py +0 -190
  345. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/node_link.py +0 -261
  346. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tree.py +0 -137
  347. package/runtime/python/okstra_vendor/networkx/readwrite/leda.py +0 -108
  348. package/runtime/python/okstra_vendor/networkx/readwrite/multiline_adjlist.py +0 -393
  349. package/runtime/python/okstra_vendor/networkx/readwrite/p2g.py +0 -113
  350. package/runtime/python/okstra_vendor/networkx/readwrite/pajek.py +0 -286
  351. package/runtime/python/okstra_vendor/networkx/readwrite/sparse6.py +0 -379
  352. package/runtime/python/okstra_vendor/networkx/readwrite/text.py +0 -851
  353. package/runtime/python/okstra_vendor/networkx/relabel.py +0 -285
  354. package/runtime/python/okstra_vendor/networkx/utils/__init__.py +0 -8
  355. package/runtime/python/okstra_vendor/networkx/utils/backends.py +0 -2171
  356. package/runtime/python/okstra_vendor/networkx/utils/configs.py +0 -396
  357. package/runtime/python/okstra_vendor/networkx/utils/decorators.py +0 -1233
  358. package/runtime/python/okstra_vendor/networkx/utils/heaps.py +0 -338
  359. package/runtime/python/okstra_vendor/networkx/utils/mapped_queue.py +0 -297
  360. package/runtime/python/okstra_vendor/networkx/utils/misc.py +0 -703
  361. package/runtime/python/okstra_vendor/networkx/utils/random_sequence.py +0 -198
  362. package/runtime/python/okstra_vendor/networkx/utils/rcm.py +0 -159
  363. package/runtime/python/okstra_vendor/networkx/utils/union_find.py +0 -106
  364. package/runtime/skills/okstra-graphify/SKILL.md +0 -169
  365. package/src/commands/graphify.mjs +0 -32
@@ -1,4 +0,0 @@
1
- from networkx.algorithms.coloring.greedy_coloring import *
2
- from networkx.algorithms.coloring.equitable_coloring import equitable_color
3
-
4
- __all__ = ["greedy_color", "equitable_color"]
@@ -1,505 +0,0 @@
1
- """
2
- Equitable coloring of graphs with bounded degree.
3
- """
4
-
5
- from collections import defaultdict
6
-
7
- import networkx as nx
8
-
9
- __all__ = ["equitable_color"]
10
-
11
-
12
- @nx._dispatchable
13
- def is_coloring(G, coloring):
14
- """Determine if the coloring is a valid coloring for the graph G."""
15
- # Verify that the coloring is valid.
16
- return all(coloring[s] != coloring[d] for s, d in G.edges)
17
-
18
-
19
- @nx._dispatchable
20
- def is_equitable(G, coloring, num_colors=None):
21
- """Determines if the coloring is valid and equitable for the graph G."""
22
-
23
- if not is_coloring(G, coloring):
24
- return False
25
-
26
- # Verify whether it is equitable.
27
- color_set_size = defaultdict(int)
28
- for color in coloring.values():
29
- color_set_size[color] += 1
30
-
31
- if num_colors is not None:
32
- for color in range(num_colors):
33
- if color not in color_set_size:
34
- # These colors do not have any vertices attached to them.
35
- color_set_size[color] = 0
36
-
37
- # If there are more than 2 distinct values, the coloring cannot be equitable
38
- all_set_sizes = set(color_set_size.values())
39
- if len(all_set_sizes) == 0 and num_colors is None: # Was an empty graph
40
- return True
41
- elif len(all_set_sizes) == 1:
42
- return True
43
- elif len(all_set_sizes) == 2:
44
- a, b = list(all_set_sizes)
45
- return abs(a - b) <= 1
46
- else: # len(all_set_sizes) > 2:
47
- return False
48
-
49
-
50
- def make_C_from_F(F):
51
- C = defaultdict(list)
52
- for node, color in F.items():
53
- C[color].append(node)
54
-
55
- return C
56
-
57
-
58
- def make_N_from_L_C(L, C):
59
- nodes = L.keys()
60
- colors = C.keys()
61
- return {
62
- (node, color): sum(1 for v in L[node] if v in C[color])
63
- for node in nodes
64
- for color in colors
65
- }
66
-
67
-
68
- def make_H_from_C_N(C, N):
69
- return {
70
- (c1, c2): sum(1 for node in C[c1] if N[(node, c2)] == 0) for c1 in C for c2 in C
71
- }
72
-
73
-
74
- def change_color(u, X, Y, N, H, F, C, L):
75
- """Change the color of 'u' from X to Y and update N, H, F, C."""
76
- assert F[u] == X and X != Y
77
-
78
- # Change the class of 'u' from X to Y
79
- F[u] = Y
80
-
81
- for k in C:
82
- # 'u' witnesses an edge from k -> Y instead of from k -> X now.
83
- if N[u, k] == 0:
84
- H[(X, k)] -= 1
85
- H[(Y, k)] += 1
86
-
87
- for v in L[u]:
88
- # 'v' has lost a neighbor in X and gained one in Y
89
- N[(v, X)] -= 1
90
- N[(v, Y)] += 1
91
-
92
- if N[(v, X)] == 0:
93
- # 'v' witnesses F[v] -> X
94
- H[(F[v], X)] += 1
95
-
96
- if N[(v, Y)] == 1:
97
- # 'v' no longer witnesses F[v] -> Y
98
- H[(F[v], Y)] -= 1
99
-
100
- C[X].remove(u)
101
- C[Y].append(u)
102
-
103
-
104
- def move_witnesses(src_color, dst_color, N, H, F, C, T_cal, L):
105
- """Move witness along a path from src_color to dst_color."""
106
- X = src_color
107
- while X != dst_color:
108
- Y = T_cal[X]
109
- # Move _any_ witness from X to Y = T_cal[X]
110
- w = next(x for x in C[X] if N[(x, Y)] == 0)
111
- change_color(w, X, Y, N=N, H=H, F=F, C=C, L=L)
112
- X = Y
113
-
114
-
115
- @nx._dispatchable(mutates_input=True)
116
- def pad_graph(G, num_colors):
117
- """Add a disconnected complete clique K_p such that the number of nodes in
118
- the graph becomes a multiple of `num_colors`.
119
-
120
- Assumes that the graph's nodes are labelled using integers.
121
-
122
- Returns the number of nodes with each color.
123
- """
124
-
125
- n_ = len(G)
126
- r = num_colors - 1
127
-
128
- # Ensure that the number of nodes in G is a multiple of (r + 1)
129
- s = n_ // (r + 1)
130
- if n_ != s * (r + 1):
131
- p = (r + 1) - n_ % (r + 1)
132
- s += 1
133
-
134
- # Complete graph K_p between (imaginary) nodes [n_, ... , n_ + p]
135
- K = nx.relabel_nodes(nx.complete_graph(p), {idx: idx + n_ for idx in range(p)})
136
- G.add_edges_from(K.edges)
137
-
138
- return s
139
-
140
-
141
- def procedure_P(V_minus, V_plus, N, H, F, C, L, excluded_colors=None):
142
- """Procedure P as described in the paper."""
143
-
144
- if excluded_colors is None:
145
- excluded_colors = set()
146
-
147
- A_cal = set()
148
- T_cal = {}
149
- R_cal = []
150
-
151
- # BFS to determine A_cal, i.e. colors reachable from V-
152
- reachable = [V_minus]
153
- marked = set(reachable)
154
- idx = 0
155
-
156
- while idx < len(reachable):
157
- pop = reachable[idx]
158
- idx += 1
159
-
160
- A_cal.add(pop)
161
- R_cal.append(pop)
162
-
163
- # TODO: Checking whether a color has been visited can be made faster by
164
- # using a look-up table instead of testing for membership in a set by a
165
- # logarithmic factor.
166
- next_layer = []
167
- for k in C:
168
- if (
169
- H[(k, pop)] > 0
170
- and k not in A_cal
171
- and k not in excluded_colors
172
- and k not in marked
173
- ):
174
- next_layer.append(k)
175
-
176
- for dst in next_layer:
177
- # Record that `dst` can reach `pop`
178
- T_cal[dst] = pop
179
-
180
- marked.update(next_layer)
181
- reachable.extend(next_layer)
182
-
183
- # Variables for the algorithm
184
- b = len(C) - len(A_cal)
185
-
186
- if V_plus in A_cal:
187
- # Easy case: V+ is in A_cal
188
- # Move one node from V+ to V- using T_cal to find the parents.
189
- move_witnesses(V_plus, V_minus, N=N, H=H, F=F, C=C, T_cal=T_cal, L=L)
190
- else:
191
- # If there is a solo edge, we can resolve the situation by
192
- # moving witnesses from B to A, making G[A] equitable and then
193
- # recursively balancing G[B - w] with a different V_minus and
194
- # but the same V_plus.
195
-
196
- A_0 = set()
197
- A_cal_0 = set()
198
- num_terminal_sets_found = 0
199
- made_equitable = False
200
-
201
- for W_1 in R_cal[::-1]:
202
- for v in C[W_1]:
203
- X = None
204
-
205
- for U in C:
206
- if N[(v, U)] == 0 and U in A_cal and U != W_1:
207
- X = U
208
-
209
- # v does not witness an edge in H[A_cal]
210
- if X is None:
211
- continue
212
-
213
- for U in C:
214
- # Note: Departing from the paper here.
215
- if N[(v, U)] >= 1 and U not in A_cal:
216
- X_prime = U
217
- w = v
218
-
219
- try:
220
- # Finding the solo neighbor of w in X_prime
221
- y = next(
222
- node
223
- for node in L[w]
224
- if F[node] == X_prime and N[(node, W_1)] == 1
225
- )
226
- except StopIteration:
227
- pass
228
- else:
229
- W = W_1
230
-
231
- # Move w from W to X, now X has one extra node.
232
- change_color(w, W, X, N=N, H=H, F=F, C=C, L=L)
233
-
234
- # Move witness from X to V_minus, making the coloring
235
- # equitable.
236
- move_witnesses(
237
- src_color=X,
238
- dst_color=V_minus,
239
- N=N,
240
- H=H,
241
- F=F,
242
- C=C,
243
- T_cal=T_cal,
244
- L=L,
245
- )
246
-
247
- # Move y from X_prime to W, making W the correct size.
248
- change_color(y, X_prime, W, N=N, H=H, F=F, C=C, L=L)
249
-
250
- # Then call the procedure on G[B - y]
251
- procedure_P(
252
- V_minus=X_prime,
253
- V_plus=V_plus,
254
- N=N,
255
- H=H,
256
- C=C,
257
- F=F,
258
- L=L,
259
- excluded_colors=excluded_colors.union(A_cal),
260
- )
261
- made_equitable = True
262
- break
263
-
264
- if made_equitable:
265
- break
266
- else:
267
- # No node in W_1 was found such that
268
- # it had a solo-neighbor.
269
- A_cal_0.add(W_1)
270
- A_0.update(C[W_1])
271
- num_terminal_sets_found += 1
272
-
273
- if num_terminal_sets_found == b:
274
- # Otherwise, construct the maximal independent set and find
275
- # a pair of z_1, z_2 as in Case II.
276
-
277
- # BFS to determine B_cal': the set of colors reachable from V+
278
- B_cal_prime = set()
279
- T_cal_prime = {}
280
-
281
- reachable = [V_plus]
282
- marked = set(reachable)
283
- idx = 0
284
- while idx < len(reachable):
285
- pop = reachable[idx]
286
- idx += 1
287
-
288
- B_cal_prime.add(pop)
289
-
290
- # No need to check for excluded_colors here because
291
- # they only exclude colors from A_cal
292
- next_layer = [
293
- k
294
- for k in C
295
- if H[(pop, k)] > 0 and k not in B_cal_prime and k not in marked
296
- ]
297
-
298
- for dst in next_layer:
299
- T_cal_prime[pop] = dst
300
-
301
- marked.update(next_layer)
302
- reachable.extend(next_layer)
303
-
304
- # Construct the independent set of G[B']
305
- I_set = set()
306
- I_covered = set()
307
- W_covering = {}
308
-
309
- B_prime = [node for k in B_cal_prime for node in C[k]]
310
-
311
- # Add the nodes in V_plus to I first.
312
- for z in C[V_plus] + B_prime:
313
- if z in I_covered or F[z] not in B_cal_prime:
314
- continue
315
-
316
- I_set.add(z)
317
- I_covered.add(z)
318
- I_covered.update(list(L[z]))
319
-
320
- for w in L[z]:
321
- if F[w] in A_cal_0 and N[(z, F[w])] == 1:
322
- if w not in W_covering:
323
- W_covering[w] = z
324
- else:
325
- # Found z1, z2 which have the same solo
326
- # neighbor in some W
327
- z_1 = W_covering[w]
328
- # z_2 = z
329
-
330
- Z = F[z_1]
331
- W = F[w]
332
-
333
- # shift nodes along W, V-
334
- move_witnesses(
335
- W, V_minus, N=N, H=H, F=F, C=C, T_cal=T_cal, L=L
336
- )
337
-
338
- # shift nodes along V+ to Z
339
- move_witnesses(
340
- V_plus,
341
- Z,
342
- N=N,
343
- H=H,
344
- F=F,
345
- C=C,
346
- T_cal=T_cal_prime,
347
- L=L,
348
- )
349
-
350
- # change color of z_1 to W
351
- change_color(z_1, Z, W, N=N, H=H, F=F, C=C, L=L)
352
-
353
- # change color of w to some color in B_cal
354
- W_plus = next(
355
- k for k in C if N[(w, k)] == 0 and k not in A_cal
356
- )
357
- change_color(w, W, W_plus, N=N, H=H, F=F, C=C, L=L)
358
-
359
- # recurse with G[B \cup W*]
360
- excluded_colors.update(
361
- [k for k in C if k != W and k not in B_cal_prime]
362
- )
363
- procedure_P(
364
- V_minus=W,
365
- V_plus=W_plus,
366
- N=N,
367
- H=H,
368
- C=C,
369
- F=F,
370
- L=L,
371
- excluded_colors=excluded_colors,
372
- )
373
-
374
- made_equitable = True
375
- break
376
-
377
- if made_equitable:
378
- break
379
- else:
380
- assert False, (
381
- "Must find a w which is the solo neighbor "
382
- "of two vertices in B_cal_prime."
383
- )
384
-
385
- if made_equitable:
386
- break
387
-
388
-
389
- @nx._dispatchable
390
- def equitable_color(G, num_colors):
391
- """Provides an equitable coloring for nodes of `G`.
392
-
393
- Attempts to color a graph using `num_colors` colors, where no neighbors of
394
- a node can have same color as the node itself and the number of nodes with
395
- each color differ by at most 1. `num_colors` must be greater than the
396
- maximum degree of `G`. The algorithm is described in [1]_ and has
397
- complexity O(num_colors * n**2).
398
-
399
- Parameters
400
- ----------
401
- G : networkX graph
402
- The nodes of this graph will be colored.
403
-
404
- num_colors : number of colors to use
405
- This number must be at least one more than the maximum degree of nodes
406
- in the graph.
407
-
408
- Returns
409
- -------
410
- A dictionary with keys representing nodes and values representing
411
- corresponding coloring.
412
-
413
- Examples
414
- --------
415
- >>> G = nx.cycle_graph(4)
416
- >>> nx.coloring.equitable_color(G, num_colors=3) # doctest: +SKIP
417
- {0: 2, 1: 1, 2: 2, 3: 0}
418
-
419
- Raises
420
- ------
421
- NetworkXAlgorithmError
422
- If `num_colors` is not at least the maximum degree of the graph `G`
423
-
424
- References
425
- ----------
426
- .. [1] Kierstead, H. A., Kostochka, A. V., Mydlarz, M., & Szemerédi, E.
427
- (2010). A fast algorithm for equitable coloring. Combinatorica, 30(2),
428
- 217-224.
429
- """
430
-
431
- # Map nodes to integers for simplicity later.
432
- nodes_to_int = {}
433
- int_to_nodes = {}
434
-
435
- for idx, node in enumerate(G.nodes):
436
- nodes_to_int[node] = idx
437
- int_to_nodes[idx] = node
438
-
439
- G = nx.relabel_nodes(G, nodes_to_int, copy=True)
440
-
441
- # Basic graph statistics and sanity check.
442
- if len(G.nodes) > 0:
443
- r_ = max(G.degree(node) for node in G.nodes)
444
- else:
445
- r_ = 0
446
-
447
- if r_ >= num_colors:
448
- raise nx.NetworkXAlgorithmError(
449
- f"Graph has maximum degree {r_}, needs "
450
- f"{r_ + 1} (> {num_colors}) colors for guaranteed coloring."
451
- )
452
-
453
- # Ensure that the number of nodes in G is a multiple of (r + 1)
454
- pad_graph(G, num_colors)
455
-
456
- # Starting the algorithm.
457
- # L = {node: list(G.neighbors(node)) for node in G.nodes}
458
- L_ = {node: [] for node in G.nodes}
459
-
460
- # Arbitrary equitable allocation of colors to nodes.
461
- F = {node: idx % num_colors for idx, node in enumerate(G.nodes)}
462
-
463
- C = make_C_from_F(F)
464
-
465
- # The neighborhood is empty initially.
466
- N = make_N_from_L_C(L_, C)
467
-
468
- # Currently all nodes witness all edges.
469
- H = make_H_from_C_N(C, N)
470
-
471
- # Start of algorithm.
472
- edges_seen = set()
473
-
474
- for u in sorted(G.nodes):
475
- for v in sorted(G.neighbors(u)):
476
- # Do not double count edges if (v, u) has already been seen.
477
- if (v, u) in edges_seen:
478
- continue
479
-
480
- edges_seen.add((u, v))
481
-
482
- L_[u].append(v)
483
- L_[v].append(u)
484
-
485
- N[(u, F[v])] += 1
486
- N[(v, F[u])] += 1
487
-
488
- if F[u] != F[v]:
489
- # Were 'u' and 'v' witnesses for F[u] -> F[v] or F[v] -> F[u]?
490
- if N[(u, F[v])] == 1:
491
- H[F[u], F[v]] -= 1 # u cannot witness an edge between F[u], F[v]
492
-
493
- if N[(v, F[u])] == 1:
494
- H[F[v], F[u]] -= 1 # v cannot witness an edge between F[v], F[u]
495
-
496
- if N[(u, F[u])] != 0:
497
- # Find the first color where 'u' does not have any neighbors.
498
- Y = next(k for k in C if N[(u, k)] == 0)
499
- X = F[u]
500
- change_color(u, X, Y, N=N, H=H, F=F, C=C, L=L_)
501
-
502
- # Procedure P
503
- procedure_P(V_minus=X, V_plus=Y, N=N, H=H, F=F, C=C, L=L_)
504
-
505
- return {int_to_nodes[x]: F[x] for x in int_to_nodes}