okstra 0.130.3 → 0.131.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 (367) 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 +21 -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/report_views.py +32 -5
  27. package/runtime/python/okstra_ctl/run.py +15 -3
  28. package/runtime/python/okstra_ctl/worker_prompt_contract.py +14 -6
  29. package/runtime/python/okstra_ctl/worker_prompt_policy.py +19 -1
  30. package/runtime/python/okstra_vendor/__init__.py +0 -44
  31. package/runtime/schemas/final-report-v1.0.schema.json +101 -6
  32. package/runtime/skills/okstra-run/SKILL.md +11 -4
  33. package/runtime/skills/okstra-setup/SKILL.md +3 -2
  34. package/runtime/skills/okstra-setup/references/project-config.md +16 -7
  35. package/runtime/templates/reports/final-report.template.md +18 -12
  36. package/runtime/templates/reports/i18n/en.json +1 -0
  37. package/runtime/templates/reports/i18n/ko.json +1 -0
  38. package/runtime/templates/reports/report.css +18 -0
  39. package/runtime/validators/lib/fixtures.sh +6 -0
  40. package/runtime/validators/validate-run.py +1722 -98
  41. package/src/cli-registry.mjs +0 -7
  42. package/src/commands/lifecycle/doctor.mjs +0 -9
  43. package/src/lib/skill-catalog.mjs +0 -1
  44. package/docs/for-ai/skills/okstra-graphify.md +0 -64
  45. package/runtime/python/okstra_ctl/graphify_cmd.py +0 -225
  46. package/runtime/python/okstra_vendor/graphify/.vendored-version +0 -1
  47. package/runtime/python/okstra_vendor/graphify/__init__.py +0 -28
  48. package/runtime/python/okstra_vendor/graphify/__main__.py +0 -1371
  49. package/runtime/python/okstra_vendor/graphify/analyze.py +0 -540
  50. package/runtime/python/okstra_vendor/graphify/benchmark.py +0 -129
  51. package/runtime/python/okstra_vendor/graphify/build.py +0 -107
  52. package/runtime/python/okstra_vendor/graphify/cache.py +0 -169
  53. package/runtime/python/okstra_vendor/graphify/cluster.py +0 -137
  54. package/runtime/python/okstra_vendor/graphify/detect.py +0 -510
  55. package/runtime/python/okstra_vendor/graphify/export.py +0 -1014
  56. package/runtime/python/okstra_vendor/graphify/extract.py +0 -3277
  57. package/runtime/python/okstra_vendor/graphify/hooks.py +0 -220
  58. package/runtime/python/okstra_vendor/graphify/ingest.py +0 -297
  59. package/runtime/python/okstra_vendor/graphify/manifest.py +0 -4
  60. package/runtime/python/okstra_vendor/graphify/report.py +0 -175
  61. package/runtime/python/okstra_vendor/graphify/security.py +0 -203
  62. package/runtime/python/okstra_vendor/graphify/serve.py +0 -373
  63. package/runtime/python/okstra_vendor/graphify/skill-aider.md +0 -1184
  64. package/runtime/python/okstra_vendor/graphify/skill-claw.md +0 -1184
  65. package/runtime/python/okstra_vendor/graphify/skill-codex.md +0 -1242
  66. package/runtime/python/okstra_vendor/graphify/skill-copilot.md +0 -1268
  67. package/runtime/python/okstra_vendor/graphify/skill-droid.md +0 -1239
  68. package/runtime/python/okstra_vendor/graphify/skill-kiro.md +0 -1183
  69. package/runtime/python/okstra_vendor/graphify/skill-opencode.md +0 -1238
  70. package/runtime/python/okstra_vendor/graphify/skill-trae.md +0 -1208
  71. package/runtime/python/okstra_vendor/graphify/skill-vscode.md +0 -253
  72. package/runtime/python/okstra_vendor/graphify/skill-windows.md +0 -1245
  73. package/runtime/python/okstra_vendor/graphify/skill.md +0 -1319
  74. package/runtime/python/okstra_vendor/graphify/transcribe.py +0 -182
  75. package/runtime/python/okstra_vendor/graphify/validate.py +0 -72
  76. package/runtime/python/okstra_vendor/graphify/watch.py +0 -188
  77. package/runtime/python/okstra_vendor/graphify/wiki.py +0 -214
  78. package/runtime/python/okstra_vendor/networkx/__init__.py +0 -62
  79. package/runtime/python/okstra_vendor/networkx/algorithms/__init__.py +0 -134
  80. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/__init__.py +0 -26
  81. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clique.py +0 -259
  82. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clustering_coefficient.py +0 -71
  83. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/connectivity.py +0 -412
  84. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/density.py +0 -396
  85. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/distance_measures.py +0 -150
  86. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/dominating_set.py +0 -149
  87. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/kcomponents.py +0 -369
  88. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/matching.py +0 -44
  89. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/maxcut.py +0 -143
  90. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/ramsey.py +0 -53
  91. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/steinertree.py +0 -265
  92. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/traveling_salesman.py +0 -1508
  93. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/treewidth.py +0 -255
  94. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/vertex_cover.py +0 -83
  95. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/__init__.py +0 -5
  96. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/connectivity.py +0 -122
  97. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/correlation.py +0 -302
  98. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/mixing.py +0 -255
  99. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/neighbor_degree.py +0 -160
  100. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/pairs.py +0 -127
  101. package/runtime/python/okstra_vendor/networkx/algorithms/asteroidal.py +0 -164
  102. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/__init__.py +0 -88
  103. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/basic.py +0 -322
  104. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/centrality.py +0 -290
  105. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/cluster.py +0 -289
  106. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/covering.py +0 -57
  107. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/edgelist.py +0 -360
  108. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/extendability.py +0 -105
  109. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/generators.py +0 -603
  110. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/link_analysis.py +0 -316
  111. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matching.py +0 -590
  112. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matrix.py +0 -232
  113. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/projection.py +0 -526
  114. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/redundancy.py +0 -112
  115. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/spectral.py +0 -69
  116. package/runtime/python/okstra_vendor/networkx/algorithms/boundary.py +0 -168
  117. package/runtime/python/okstra_vendor/networkx/algorithms/bridges.py +0 -205
  118. package/runtime/python/okstra_vendor/networkx/algorithms/broadcasting.py +0 -164
  119. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/__init__.py +0 -20
  120. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness.py +0 -591
  121. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness_subset.py +0 -236
  122. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/closeness.py +0 -282
  123. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness.py +0 -364
  124. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness_subset.py +0 -227
  125. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_closeness.py +0 -96
  126. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/degree_alg.py +0 -150
  127. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/dispersion.py +0 -107
  128. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/eigenvector.py +0 -357
  129. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/flow_matrix.py +0 -130
  130. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/group.py +0 -787
  131. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/harmonic.py +0 -88
  132. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/katz.py +0 -331
  133. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/laplacian.py +0 -150
  134. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/load.py +0 -200
  135. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/percolation.py +0 -128
  136. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/reaching.py +0 -209
  137. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/second_order.py +0 -141
  138. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/subgraph_alg.py +0 -361
  139. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/trophic.py +0 -181
  140. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/voterank_alg.py +0 -95
  141. package/runtime/python/okstra_vendor/networkx/algorithms/chains.py +0 -172
  142. package/runtime/python/okstra_vendor/networkx/algorithms/chordal.py +0 -443
  143. package/runtime/python/okstra_vendor/networkx/algorithms/clique.py +0 -818
  144. package/runtime/python/okstra_vendor/networkx/algorithms/cluster.py +0 -732
  145. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/__init__.py +0 -4
  146. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/equitable_coloring.py +0 -505
  147. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/greedy_coloring.py +0 -565
  148. package/runtime/python/okstra_vendor/networkx/algorithms/communicability_alg.py +0 -163
  149. package/runtime/python/okstra_vendor/networkx/algorithms/community/__init__.py +0 -28
  150. package/runtime/python/okstra_vendor/networkx/algorithms/community/asyn_fluid.py +0 -153
  151. package/runtime/python/okstra_vendor/networkx/algorithms/community/bipartitions.py +0 -354
  152. package/runtime/python/okstra_vendor/networkx/algorithms/community/centrality.py +0 -171
  153. package/runtime/python/okstra_vendor/networkx/algorithms/community/community_utils.py +0 -30
  154. package/runtime/python/okstra_vendor/networkx/algorithms/community/divisive.py +0 -216
  155. package/runtime/python/okstra_vendor/networkx/algorithms/community/kclique.py +0 -79
  156. package/runtime/python/okstra_vendor/networkx/algorithms/community/label_propagation.py +0 -338
  157. package/runtime/python/okstra_vendor/networkx/algorithms/community/leiden.py +0 -162
  158. package/runtime/python/okstra_vendor/networkx/algorithms/community/local.py +0 -220
  159. package/runtime/python/okstra_vendor/networkx/algorithms/community/louvain.py +0 -384
  160. package/runtime/python/okstra_vendor/networkx/algorithms/community/lukes.py +0 -227
  161. package/runtime/python/okstra_vendor/networkx/algorithms/community/modularity_max.py +0 -452
  162. package/runtime/python/okstra_vendor/networkx/algorithms/community/quality.py +0 -347
  163. package/runtime/python/okstra_vendor/networkx/algorithms/components/__init__.py +0 -6
  164. package/runtime/python/okstra_vendor/networkx/algorithms/components/attracting.py +0 -115
  165. package/runtime/python/okstra_vendor/networkx/algorithms/components/biconnected.py +0 -394
  166. package/runtime/python/okstra_vendor/networkx/algorithms/components/connected.py +0 -282
  167. package/runtime/python/okstra_vendor/networkx/algorithms/components/semiconnected.py +0 -71
  168. package/runtime/python/okstra_vendor/networkx/algorithms/components/strongly_connected.py +0 -359
  169. package/runtime/python/okstra_vendor/networkx/algorithms/components/weakly_connected.py +0 -196
  170. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/__init__.py +0 -11
  171. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/connectivity.py +0 -811
  172. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/cuts.py +0 -616
  173. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/disjoint_paths.py +0 -408
  174. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_augmentation.py +0 -1270
  175. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_kcomponents.py +0 -592
  176. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcomponents.py +0 -220
  177. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcutsets.py +0 -235
  178. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/stoerwagner.py +0 -152
  179. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/utils.py +0 -88
  180. package/runtime/python/okstra_vendor/networkx/algorithms/core.py +0 -588
  181. package/runtime/python/okstra_vendor/networkx/algorithms/covering.py +0 -142
  182. package/runtime/python/okstra_vendor/networkx/algorithms/cuts.py +0 -416
  183. package/runtime/python/okstra_vendor/networkx/algorithms/cycles.py +0 -1234
  184. package/runtime/python/okstra_vendor/networkx/algorithms/d_separation.py +0 -677
  185. package/runtime/python/okstra_vendor/networkx/algorithms/dag.py +0 -1392
  186. package/runtime/python/okstra_vendor/networkx/algorithms/distance_measures.py +0 -1095
  187. package/runtime/python/okstra_vendor/networkx/algorithms/distance_regular.py +0 -272
  188. package/runtime/python/okstra_vendor/networkx/algorithms/dominance.py +0 -142
  189. package/runtime/python/okstra_vendor/networkx/algorithms/dominating.py +0 -268
  190. package/runtime/python/okstra_vendor/networkx/algorithms/efficiency_measures.py +0 -167
  191. package/runtime/python/okstra_vendor/networkx/algorithms/euler.py +0 -470
  192. package/runtime/python/okstra_vendor/networkx/algorithms/flow/__init__.py +0 -11
  193. package/runtime/python/okstra_vendor/networkx/algorithms/flow/boykovkolmogorov.py +0 -370
  194. package/runtime/python/okstra_vendor/networkx/algorithms/flow/capacityscaling.py +0 -407
  195. package/runtime/python/okstra_vendor/networkx/algorithms/flow/dinitz_alg.py +0 -238
  196. package/runtime/python/okstra_vendor/networkx/algorithms/flow/edmondskarp.py +0 -241
  197. package/runtime/python/okstra_vendor/networkx/algorithms/flow/gomory_hu.py +0 -178
  198. package/runtime/python/okstra_vendor/networkx/algorithms/flow/maxflow.py +0 -611
  199. package/runtime/python/okstra_vendor/networkx/algorithms/flow/mincost.py +0 -356
  200. package/runtime/python/okstra_vendor/networkx/algorithms/flow/networksimplex.py +0 -662
  201. package/runtime/python/okstra_vendor/networkx/algorithms/flow/preflowpush.py +0 -425
  202. package/runtime/python/okstra_vendor/networkx/algorithms/flow/shortestaugmentingpath.py +0 -300
  203. package/runtime/python/okstra_vendor/networkx/algorithms/flow/utils.py +0 -194
  204. package/runtime/python/okstra_vendor/networkx/algorithms/graph_hashing.py +0 -435
  205. package/runtime/python/okstra_vendor/networkx/algorithms/graphical.py +0 -483
  206. package/runtime/python/okstra_vendor/networkx/algorithms/hierarchy.py +0 -57
  207. package/runtime/python/okstra_vendor/networkx/algorithms/hybrid.py +0 -196
  208. package/runtime/python/okstra_vendor/networkx/algorithms/isolate.py +0 -107
  209. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/__init__.py +0 -7
  210. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/ismags.py +0 -1306
  211. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorph.py +0 -336
  212. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorphvf2.py +0 -1262
  213. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/matchhelpers.py +0 -352
  214. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/temporalisomorphvf2.py +0 -308
  215. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tree_isomorphism.py +0 -264
  216. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2pp.py +0 -1102
  217. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2userfunc.py +0 -192
  218. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/__init__.py +0 -2
  219. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/hits_alg.py +0 -337
  220. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/pagerank_alg.py +0 -498
  221. package/runtime/python/okstra_vendor/networkx/algorithms/link_prediction.py +0 -687
  222. package/runtime/python/okstra_vendor/networkx/algorithms/lowest_common_ancestors.py +0 -280
  223. package/runtime/python/okstra_vendor/networkx/algorithms/matching.py +0 -1148
  224. package/runtime/python/okstra_vendor/networkx/algorithms/minors/__init__.py +0 -27
  225. package/runtime/python/okstra_vendor/networkx/algorithms/minors/contraction.py +0 -738
  226. package/runtime/python/okstra_vendor/networkx/algorithms/mis.py +0 -78
  227. package/runtime/python/okstra_vendor/networkx/algorithms/moral.py +0 -59
  228. package/runtime/python/okstra_vendor/networkx/algorithms/node_classification.py +0 -219
  229. package/runtime/python/okstra_vendor/networkx/algorithms/non_randomness.py +0 -155
  230. package/runtime/python/okstra_vendor/networkx/algorithms/operators/__init__.py +0 -4
  231. package/runtime/python/okstra_vendor/networkx/algorithms/operators/all.py +0 -324
  232. package/runtime/python/okstra_vendor/networkx/algorithms/operators/binary.py +0 -468
  233. package/runtime/python/okstra_vendor/networkx/algorithms/operators/product.py +0 -633
  234. package/runtime/python/okstra_vendor/networkx/algorithms/operators/unary.py +0 -77
  235. package/runtime/python/okstra_vendor/networkx/algorithms/perfect_graph.py +0 -73
  236. package/runtime/python/okstra_vendor/networkx/algorithms/planar_drawing.py +0 -464
  237. package/runtime/python/okstra_vendor/networkx/algorithms/planarity.py +0 -1463
  238. package/runtime/python/okstra_vendor/networkx/algorithms/polynomials.py +0 -306
  239. package/runtime/python/okstra_vendor/networkx/algorithms/reciprocity.py +0 -98
  240. package/runtime/python/okstra_vendor/networkx/algorithms/regular.py +0 -167
  241. package/runtime/python/okstra_vendor/networkx/algorithms/richclub.py +0 -138
  242. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/__init__.py +0 -5
  243. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/astar.py +0 -239
  244. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/dense.py +0 -264
  245. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/generic.py +0 -716
  246. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/unweighted.py +0 -625
  247. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/weighted.py +0 -2542
  248. package/runtime/python/okstra_vendor/networkx/algorithms/similarity.py +0 -2107
  249. package/runtime/python/okstra_vendor/networkx/algorithms/simple_paths.py +0 -966
  250. package/runtime/python/okstra_vendor/networkx/algorithms/smallworld.py +0 -404
  251. package/runtime/python/okstra_vendor/networkx/algorithms/smetric.py +0 -30
  252. package/runtime/python/okstra_vendor/networkx/algorithms/sparsifiers.py +0 -296
  253. package/runtime/python/okstra_vendor/networkx/algorithms/structuralholes.py +0 -374
  254. package/runtime/python/okstra_vendor/networkx/algorithms/summarization.py +0 -564
  255. package/runtime/python/okstra_vendor/networkx/algorithms/swap.py +0 -406
  256. package/runtime/python/okstra_vendor/networkx/algorithms/threshold.py +0 -981
  257. package/runtime/python/okstra_vendor/networkx/algorithms/time_dependent.py +0 -142
  258. package/runtime/python/okstra_vendor/networkx/algorithms/tournament.py +0 -406
  259. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/__init__.py +0 -5
  260. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/beamsearch.py +0 -90
  261. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/breadth_first_search.py +0 -576
  262. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/depth_first_search.py +0 -529
  263. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgebfs.py +0 -185
  264. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgedfs.py +0 -182
  265. package/runtime/python/okstra_vendor/networkx/algorithms/tree/__init__.py +0 -7
  266. package/runtime/python/okstra_vendor/networkx/algorithms/tree/branchings.py +0 -1042
  267. package/runtime/python/okstra_vendor/networkx/algorithms/tree/coding.py +0 -413
  268. package/runtime/python/okstra_vendor/networkx/algorithms/tree/decomposition.py +0 -88
  269. package/runtime/python/okstra_vendor/networkx/algorithms/tree/distance_measures.py +0 -219
  270. package/runtime/python/okstra_vendor/networkx/algorithms/tree/mst.py +0 -1281
  271. package/runtime/python/okstra_vendor/networkx/algorithms/tree/operations.py +0 -106
  272. package/runtime/python/okstra_vendor/networkx/algorithms/tree/recognition.py +0 -273
  273. package/runtime/python/okstra_vendor/networkx/algorithms/triads.py +0 -500
  274. package/runtime/python/okstra_vendor/networkx/algorithms/vitality.py +0 -76
  275. package/runtime/python/okstra_vendor/networkx/algorithms/voronoi.py +0 -86
  276. package/runtime/python/okstra_vendor/networkx/algorithms/walks.py +0 -77
  277. package/runtime/python/okstra_vendor/networkx/algorithms/wiener.py +0 -278
  278. package/runtime/python/okstra_vendor/networkx/classes/__init__.py +0 -13
  279. package/runtime/python/okstra_vendor/networkx/classes/coreviews.py +0 -435
  280. package/runtime/python/okstra_vendor/networkx/classes/digraph.py +0 -1363
  281. package/runtime/python/okstra_vendor/networkx/classes/filters.py +0 -95
  282. package/runtime/python/okstra_vendor/networkx/classes/function.py +0 -1549
  283. package/runtime/python/okstra_vendor/networkx/classes/graph.py +0 -2082
  284. package/runtime/python/okstra_vendor/networkx/classes/graphviews.py +0 -269
  285. package/runtime/python/okstra_vendor/networkx/classes/multidigraph.py +0 -977
  286. package/runtime/python/okstra_vendor/networkx/classes/multigraph.py +0 -1294
  287. package/runtime/python/okstra_vendor/networkx/classes/reportviews.py +0 -1447
  288. package/runtime/python/okstra_vendor/networkx/convert.py +0 -502
  289. package/runtime/python/okstra_vendor/networkx/convert_matrix.py +0 -1314
  290. package/runtime/python/okstra_vendor/networkx/drawing/__init__.py +0 -7
  291. package/runtime/python/okstra_vendor/networkx/drawing/layout.py +0 -2036
  292. package/runtime/python/okstra_vendor/networkx/drawing/nx_agraph.py +0 -470
  293. package/runtime/python/okstra_vendor/networkx/drawing/nx_latex.py +0 -570
  294. package/runtime/python/okstra_vendor/networkx/drawing/nx_pydot.py +0 -361
  295. package/runtime/python/okstra_vendor/networkx/drawing/nx_pylab.py +0 -2978
  296. package/runtime/python/okstra_vendor/networkx/exception.py +0 -131
  297. package/runtime/python/okstra_vendor/networkx/generators/__init__.py +0 -34
  298. package/runtime/python/okstra_vendor/networkx/generators/atlas.dat.gz +0 -0
  299. package/runtime/python/okstra_vendor/networkx/generators/atlas.py +0 -227
  300. package/runtime/python/okstra_vendor/networkx/generators/classic.py +0 -1091
  301. package/runtime/python/okstra_vendor/networkx/generators/cographs.py +0 -68
  302. package/runtime/python/okstra_vendor/networkx/generators/community.py +0 -1070
  303. package/runtime/python/okstra_vendor/networkx/generators/degree_seq.py +0 -886
  304. package/runtime/python/okstra_vendor/networkx/generators/directed.py +0 -572
  305. package/runtime/python/okstra_vendor/networkx/generators/duplication.py +0 -174
  306. package/runtime/python/okstra_vendor/networkx/generators/ego.py +0 -66
  307. package/runtime/python/okstra_vendor/networkx/generators/expanders.py +0 -499
  308. package/runtime/python/okstra_vendor/networkx/generators/geometric.py +0 -1037
  309. package/runtime/python/okstra_vendor/networkx/generators/harary_graph.py +0 -163
  310. package/runtime/python/okstra_vendor/networkx/generators/internet_as_graphs.py +0 -443
  311. package/runtime/python/okstra_vendor/networkx/generators/intersection.py +0 -125
  312. package/runtime/python/okstra_vendor/networkx/generators/interval_graph.py +0 -70
  313. package/runtime/python/okstra_vendor/networkx/generators/joint_degree_seq.py +0 -664
  314. package/runtime/python/okstra_vendor/networkx/generators/lattice.py +0 -405
  315. package/runtime/python/okstra_vendor/networkx/generators/line.py +0 -501
  316. package/runtime/python/okstra_vendor/networkx/generators/mycielski.py +0 -110
  317. package/runtime/python/okstra_vendor/networkx/generators/nonisomorphic_trees.py +0 -259
  318. package/runtime/python/okstra_vendor/networkx/generators/random_clustered.py +0 -117
  319. package/runtime/python/okstra_vendor/networkx/generators/random_graphs.py +0 -1416
  320. package/runtime/python/okstra_vendor/networkx/generators/small.py +0 -1070
  321. package/runtime/python/okstra_vendor/networkx/generators/social.py +0 -554
  322. package/runtime/python/okstra_vendor/networkx/generators/spectral_graph_forge.py +0 -120
  323. package/runtime/python/okstra_vendor/networkx/generators/stochastic.py +0 -54
  324. package/runtime/python/okstra_vendor/networkx/generators/sudoku.py +0 -131
  325. package/runtime/python/okstra_vendor/networkx/generators/time_series.py +0 -74
  326. package/runtime/python/okstra_vendor/networkx/generators/trees.py +0 -1070
  327. package/runtime/python/okstra_vendor/networkx/generators/triads.py +0 -94
  328. package/runtime/python/okstra_vendor/networkx/lazy_imports.py +0 -188
  329. package/runtime/python/okstra_vendor/networkx/linalg/__init__.py +0 -13
  330. package/runtime/python/okstra_vendor/networkx/linalg/algebraicconnectivity.py +0 -650
  331. package/runtime/python/okstra_vendor/networkx/linalg/attrmatrix.py +0 -466
  332. package/runtime/python/okstra_vendor/networkx/linalg/bethehessianmatrix.py +0 -77
  333. package/runtime/python/okstra_vendor/networkx/linalg/graphmatrix.py +0 -168
  334. package/runtime/python/okstra_vendor/networkx/linalg/laplacianmatrix.py +0 -512
  335. package/runtime/python/okstra_vendor/networkx/linalg/modularitymatrix.py +0 -166
  336. package/runtime/python/okstra_vendor/networkx/linalg/spectrum.py +0 -186
  337. package/runtime/python/okstra_vendor/networkx/readwrite/__init__.py +0 -17
  338. package/runtime/python/okstra_vendor/networkx/readwrite/adjlist.py +0 -330
  339. package/runtime/python/okstra_vendor/networkx/readwrite/edgelist.py +0 -489
  340. package/runtime/python/okstra_vendor/networkx/readwrite/gexf.py +0 -1084
  341. package/runtime/python/okstra_vendor/networkx/readwrite/gml.py +0 -879
  342. package/runtime/python/okstra_vendor/networkx/readwrite/graph6.py +0 -427
  343. package/runtime/python/okstra_vendor/networkx/readwrite/graphml.py +0 -1053
  344. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/__init__.py +0 -19
  345. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/adjacency.py +0 -156
  346. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/cytoscape.py +0 -190
  347. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/node_link.py +0 -261
  348. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tree.py +0 -137
  349. package/runtime/python/okstra_vendor/networkx/readwrite/leda.py +0 -108
  350. package/runtime/python/okstra_vendor/networkx/readwrite/multiline_adjlist.py +0 -393
  351. package/runtime/python/okstra_vendor/networkx/readwrite/p2g.py +0 -113
  352. package/runtime/python/okstra_vendor/networkx/readwrite/pajek.py +0 -286
  353. package/runtime/python/okstra_vendor/networkx/readwrite/sparse6.py +0 -379
  354. package/runtime/python/okstra_vendor/networkx/readwrite/text.py +0 -851
  355. package/runtime/python/okstra_vendor/networkx/relabel.py +0 -285
  356. package/runtime/python/okstra_vendor/networkx/utils/__init__.py +0 -8
  357. package/runtime/python/okstra_vendor/networkx/utils/backends.py +0 -2171
  358. package/runtime/python/okstra_vendor/networkx/utils/configs.py +0 -396
  359. package/runtime/python/okstra_vendor/networkx/utils/decorators.py +0 -1233
  360. package/runtime/python/okstra_vendor/networkx/utils/heaps.py +0 -338
  361. package/runtime/python/okstra_vendor/networkx/utils/mapped_queue.py +0 -297
  362. package/runtime/python/okstra_vendor/networkx/utils/misc.py +0 -703
  363. package/runtime/python/okstra_vendor/networkx/utils/random_sequence.py +0 -198
  364. package/runtime/python/okstra_vendor/networkx/utils/rcm.py +0 -159
  365. package/runtime/python/okstra_vendor/networkx/utils/union_find.py +0 -106
  366. package/runtime/skills/okstra-graphify/SKILL.md +0 -169
  367. package/src/commands/graphify.mjs +0 -32
@@ -1,338 +0,0 @@
1
- """
2
- Min-heaps.
3
- """
4
-
5
- from heapq import heappop, heappush
6
- from itertools import count
7
-
8
- import networkx as nx
9
-
10
- __all__ = ["MinHeap", "PairingHeap", "BinaryHeap"]
11
-
12
-
13
- class MinHeap:
14
- """Base class for min-heaps.
15
-
16
- A MinHeap stores a collection of key-value pairs ordered by their values.
17
- It supports querying the minimum pair, inserting a new pair, decreasing the
18
- value in an existing pair and deleting the minimum pair.
19
- """
20
-
21
- class _Item:
22
- """Used by subclassess to represent a key-value pair."""
23
-
24
- __slots__ = ("key", "value")
25
-
26
- def __init__(self, key, value):
27
- self.key = key
28
- self.value = value
29
-
30
- def __repr__(self):
31
- return repr((self.key, self.value))
32
-
33
- def __init__(self):
34
- """Initialize a new min-heap."""
35
- self._dict = {}
36
-
37
- def min(self):
38
- """Query the minimum key-value pair.
39
-
40
- Returns
41
- -------
42
- key, value : tuple
43
- The key-value pair with the minimum value in the heap.
44
-
45
- Raises
46
- ------
47
- NetworkXError
48
- If the heap is empty.
49
- """
50
- raise NotImplementedError
51
-
52
- def pop(self):
53
- """Delete the minimum pair in the heap.
54
-
55
- Returns
56
- -------
57
- key, value : tuple
58
- The key-value pair with the minimum value in the heap.
59
-
60
- Raises
61
- ------
62
- NetworkXError
63
- If the heap is empty.
64
- """
65
- raise NotImplementedError
66
-
67
- def get(self, key, default=None):
68
- """Returns the value associated with a key.
69
-
70
- Parameters
71
- ----------
72
- key : hashable object
73
- The key to be looked up.
74
-
75
- default : object
76
- Default value to return if the key is not present in the heap.
77
- Default value: None.
78
-
79
- Returns
80
- -------
81
- value : object.
82
- The value associated with the key.
83
- """
84
- raise NotImplementedError
85
-
86
- def insert(self, key, value, allow_increase=False):
87
- """Insert a new key-value pair or modify the value in an existing
88
- pair.
89
-
90
- Parameters
91
- ----------
92
- key : hashable object
93
- The key.
94
-
95
- value : object comparable with existing values.
96
- The value.
97
-
98
- allow_increase : bool
99
- Whether the value is allowed to increase. If False, attempts to
100
- increase an existing value have no effect. Default value: False.
101
-
102
- Returns
103
- -------
104
- decreased : bool
105
- True if a pair is inserted or the existing value is decreased.
106
- """
107
- raise NotImplementedError
108
-
109
- def __nonzero__(self):
110
- """Returns whether the heap if empty."""
111
- return bool(self._dict)
112
-
113
- def __bool__(self):
114
- """Returns whether the heap if empty."""
115
- return bool(self._dict)
116
-
117
- def __len__(self):
118
- """Returns the number of key-value pairs in the heap."""
119
- return len(self._dict)
120
-
121
- def __contains__(self, key):
122
- """Returns whether a key exists in the heap.
123
-
124
- Parameters
125
- ----------
126
- key : any hashable object.
127
- The key to be looked up.
128
- """
129
- return key in self._dict
130
-
131
-
132
- class PairingHeap(MinHeap):
133
- """A pairing heap."""
134
-
135
- class _Node(MinHeap._Item):
136
- """A node in a pairing heap.
137
-
138
- A tree in a pairing heap is stored using the left-child, right-sibling
139
- representation.
140
- """
141
-
142
- __slots__ = ("left", "next", "prev", "parent")
143
-
144
- def __init__(self, key, value):
145
- super().__init__(key, value)
146
- # The leftmost child.
147
- self.left = None
148
- # The next sibling.
149
- self.next = None
150
- # The previous sibling.
151
- self.prev = None
152
- # The parent.
153
- self.parent = None
154
-
155
- def __init__(self):
156
- """Initialize a pairing heap."""
157
- super().__init__()
158
- self._root = None
159
-
160
- def min(self):
161
- if self._root is None:
162
- raise nx.NetworkXError("heap is empty.")
163
- return (self._root.key, self._root.value)
164
-
165
- def pop(self):
166
- if self._root is None:
167
- raise nx.NetworkXError("heap is empty.")
168
- min_node = self._root
169
- self._root = self._merge_children(self._root)
170
- del self._dict[min_node.key]
171
- return (min_node.key, min_node.value)
172
-
173
- def get(self, key, default=None):
174
- node = self._dict.get(key)
175
- return node.value if node is not None else default
176
-
177
- def insert(self, key, value, allow_increase=False):
178
- node = self._dict.get(key)
179
- root = self._root
180
- if node is not None:
181
- if value < node.value:
182
- node.value = value
183
- if node is not root and value < node.parent.value:
184
- self._cut(node)
185
- self._root = self._link(root, node)
186
- return True
187
- elif allow_increase and value > node.value:
188
- node.value = value
189
- child = self._merge_children(node)
190
- # Nonstandard step: Link the merged subtree with the root. See
191
- # below for the standard step.
192
- if child is not None:
193
- self._root = self._link(self._root, child)
194
- # Standard step: Perform a decrease followed by a pop as if the
195
- # value were the smallest in the heap. Then insert the new
196
- # value into the heap.
197
- # if node is not root:
198
- # self._cut(node)
199
- # if child is not None:
200
- # root = self._link(root, child)
201
- # self._root = self._link(root, node)
202
- # else:
203
- # self._root = (self._link(node, child)
204
- # if child is not None else node)
205
- return False
206
- else:
207
- # Insert a new key.
208
- node = self._Node(key, value)
209
- self._dict[key] = node
210
- self._root = self._link(root, node) if root is not None else node
211
- return True
212
-
213
- def _link(self, root, other):
214
- """Link two nodes, making the one with the smaller value the parent of
215
- the other.
216
- """
217
- if other.value < root.value:
218
- root, other = other, root
219
- next = root.left
220
- other.next = next
221
- if next is not None:
222
- next.prev = other
223
- other.prev = None
224
- root.left = other
225
- other.parent = root
226
- return root
227
-
228
- def _merge_children(self, root):
229
- """Merge the subtrees of the root using the standard two-pass method.
230
- The resulting subtree is detached from the root.
231
- """
232
- node = root.left
233
- root.left = None
234
- if node is not None:
235
- link = self._link
236
- # Pass 1: Merge pairs of consecutive subtrees from left to right.
237
- # At the end of the pass, only the prev pointers of the resulting
238
- # subtrees have meaningful values. The other pointers will be fixed
239
- # in pass 2.
240
- prev = None
241
- while True:
242
- next = node.next
243
- if next is None:
244
- node.prev = prev
245
- break
246
- next_next = next.next
247
- node = link(node, next)
248
- node.prev = prev
249
- prev = node
250
- if next_next is None:
251
- break
252
- node = next_next
253
- # Pass 2: Successively merge the subtrees produced by pass 1 from
254
- # right to left with the rightmost one.
255
- prev = node.prev
256
- while prev is not None:
257
- prev_prev = prev.prev
258
- node = link(prev, node)
259
- prev = prev_prev
260
- # Now node can become the new root. Its has no parent nor siblings.
261
- node.prev = None
262
- node.next = None
263
- node.parent = None
264
- return node
265
-
266
- def _cut(self, node):
267
- """Cut a node from its parent."""
268
- prev = node.prev
269
- next = node.next
270
- if prev is not None:
271
- prev.next = next
272
- else:
273
- node.parent.left = next
274
- node.prev = None
275
- if next is not None:
276
- next.prev = prev
277
- node.next = None
278
- node.parent = None
279
-
280
-
281
- class BinaryHeap(MinHeap):
282
- """A binary heap."""
283
-
284
- def __init__(self):
285
- """Initialize a binary heap."""
286
- super().__init__()
287
- self._heap = []
288
- self._count = count()
289
-
290
- def min(self):
291
- dict = self._dict
292
- if not dict:
293
- raise nx.NetworkXError("heap is empty")
294
- heap = self._heap
295
- # Repeatedly remove stale key-value pairs until a up-to-date one is
296
- # met.
297
- while True:
298
- value, _, key = heap[0]
299
- if key in dict and value == dict[key]:
300
- break
301
- heappop(heap)
302
- return (key, value)
303
-
304
- def pop(self):
305
- dict = self._dict
306
- if not dict:
307
- raise nx.NetworkXError("heap is empty")
308
- heap = self._heap
309
- # Repeatedly remove stale key-value pairs until a up-to-date one is
310
- # met.
311
- while True:
312
- value, _, key = heap[0]
313
- heappop(heap)
314
- if key in dict and value == dict[key]:
315
- break
316
- del dict[key]
317
- return (key, value)
318
-
319
- def get(self, key, default=None):
320
- return self._dict.get(key, default)
321
-
322
- def insert(self, key, value, allow_increase=False):
323
- dict = self._dict
324
- if key in dict:
325
- old_value = dict[key]
326
- if value < old_value or (allow_increase and value > old_value):
327
- # Since there is no way to efficiently obtain the location of a
328
- # key-value pair in the heap, insert a new pair even if ones
329
- # with the same key may already be present. Deem the old ones
330
- # as stale and skip them when the minimum pair is queried.
331
- dict[key] = value
332
- heappush(self._heap, (value, next(self._count), key))
333
- return value < old_value
334
- return False
335
- else:
336
- dict[key] = value
337
- heappush(self._heap, (value, next(self._count), key))
338
- return True
@@ -1,297 +0,0 @@
1
- """Priority queue class with updatable priorities."""
2
-
3
- import heapq
4
-
5
- __all__ = ["MappedQueue"]
6
-
7
-
8
- class _HeapElement:
9
- """This proxy class separates the heap element from its priority.
10
-
11
- The idea is that using a 2-tuple (priority, element) works
12
- for sorting, but not for dict lookup because priorities are
13
- often floating point values so round-off can mess up equality.
14
-
15
- So, we need inequalities to look at the priority (for sorting)
16
- and equality (and hash) to look at the element to enable
17
- updates to the priority.
18
-
19
- Unfortunately, this class can be tricky to work with if you forget that
20
- `__lt__` compares the priority while `__eq__` compares the element.
21
- In `greedy_modularity_communities()` the following code is
22
- used to check that two _HeapElements differ in either element or priority:
23
-
24
- if d_oldmax != row_max or d_oldmax.priority != row_max.priority:
25
-
26
- If the priorities are the same, this implementation uses the element
27
- as a tiebreaker. This provides compatibility with older systems that
28
- use tuples to combine priority and elements.
29
- """
30
-
31
- __slots__ = ["priority", "element", "_hash"]
32
-
33
- def __init__(self, priority, element):
34
- self.priority = priority
35
- self.element = element
36
- self._hash = hash(element)
37
-
38
- def __lt__(self, other):
39
- try:
40
- other_priority = other.priority
41
- except AttributeError:
42
- return self.priority < other
43
- # assume comparing to another _HeapElement
44
- if self.priority == other_priority:
45
- try:
46
- return self.element < other.element
47
- except TypeError as err:
48
- raise TypeError(
49
- "Consider using a tuple, with a priority value that can be compared."
50
- )
51
- return self.priority < other_priority
52
-
53
- def __gt__(self, other):
54
- try:
55
- other_priority = other.priority
56
- except AttributeError:
57
- return self.priority > other
58
- # assume comparing to another _HeapElement
59
- if self.priority == other_priority:
60
- try:
61
- return self.element > other.element
62
- except TypeError as err:
63
- raise TypeError(
64
- "Consider using a tuple, with a priority value that can be compared."
65
- )
66
- return self.priority > other_priority
67
-
68
- def __eq__(self, other):
69
- try:
70
- return self.element == other.element
71
- except AttributeError:
72
- return self.element == other
73
-
74
- def __hash__(self):
75
- return self._hash
76
-
77
- def __getitem__(self, indx):
78
- return self.priority if indx == 0 else self.element[indx - 1]
79
-
80
- def __iter__(self):
81
- yield self.priority
82
- try:
83
- yield from self.element
84
- except TypeError:
85
- yield self.element
86
-
87
- def __repr__(self):
88
- return f"_HeapElement({self.priority}, {self.element})"
89
-
90
-
91
- class MappedQueue:
92
- """The MappedQueue class implements a min-heap with removal and update-priority.
93
-
94
- The min heap uses heapq as well as custom written _siftup and _siftdown
95
- methods to allow the heap positions to be tracked by an additional dict
96
- keyed by element to position. The smallest element can be popped in O(1) time,
97
- new elements can be pushed in O(log n) time, and any element can be removed
98
- or updated in O(log n) time. The queue cannot contain duplicate elements
99
- and an attempt to push an element already in the queue will have no effect.
100
-
101
- MappedQueue complements the heapq package from the python standard
102
- library. While MappedQueue is designed for maximum compatibility with
103
- heapq, it adds element removal, lookup, and priority update.
104
-
105
- Parameters
106
- ----------
107
- data : dict or iterable
108
-
109
- Examples
110
- --------
111
-
112
- A `MappedQueue` can be created empty, or optionally, given a dictionary
113
- of initial elements and priorities. The methods `push`, `pop`,
114
- `remove`, and `update` operate on the queue.
115
-
116
- >>> colors_nm = {"red": 665, "blue": 470, "green": 550}
117
- >>> q = MappedQueue(colors_nm)
118
- >>> q.remove("red")
119
- >>> q.update("green", "violet", 400)
120
- >>> q.push("indigo", 425)
121
- True
122
- >>> [q.pop().element for i in range(len(q.heap))]
123
- ['violet', 'indigo', 'blue']
124
-
125
- A `MappedQueue` can also be initialized with a list or other iterable. The priority is assumed
126
- to be the sort order of the items in the list.
127
-
128
- >>> q = MappedQueue([916, 50, 4609, 493, 237])
129
- >>> q.remove(493)
130
- >>> q.update(237, 1117)
131
- >>> [q.pop() for i in range(len(q.heap))]
132
- [50, 916, 1117, 4609]
133
-
134
- An exception is raised if the elements are not comparable.
135
-
136
- >>> q = MappedQueue([100, "a"])
137
- Traceback (most recent call last):
138
- ...
139
- TypeError: '<' not supported between instances of 'int' and 'str'
140
-
141
- To avoid the exception, use a dictionary to assign priorities to the elements.
142
-
143
- >>> q = MappedQueue({100: 0, "a": 1})
144
-
145
- References
146
- ----------
147
- .. [1] Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. (2001).
148
- Introduction to algorithms second edition.
149
- .. [2] Knuth, D. E. (1997). The art of computer programming (Vol. 3).
150
- Pearson Education.
151
- """
152
-
153
- def __init__(self, data=None):
154
- """Priority queue class with updatable priorities."""
155
- if data is None:
156
- self.heap = []
157
- elif isinstance(data, dict):
158
- self.heap = [_HeapElement(v, k) for k, v in data.items()]
159
- else:
160
- self.heap = list(data)
161
- self.position = {}
162
- self._heapify()
163
-
164
- def _heapify(self):
165
- """Restore heap invariant and recalculate map."""
166
- heapq.heapify(self.heap)
167
- self.position = {elt: pos for pos, elt in enumerate(self.heap)}
168
- if len(self.heap) != len(self.position):
169
- raise AssertionError("Heap contains duplicate elements")
170
-
171
- def __len__(self):
172
- return len(self.heap)
173
-
174
- def push(self, elt, priority=None):
175
- """Add an element to the queue."""
176
- if priority is not None:
177
- elt = _HeapElement(priority, elt)
178
- # If element is already in queue, do nothing
179
- if elt in self.position:
180
- return False
181
- # Add element to heap and dict
182
- pos = len(self.heap)
183
- self.heap.append(elt)
184
- self.position[elt] = pos
185
- # Restore invariant by sifting down
186
- self._siftdown(0, pos)
187
- return True
188
-
189
- def pop(self):
190
- """Remove and return the smallest element in the queue."""
191
- # Remove smallest element
192
- elt = self.heap[0]
193
- del self.position[elt]
194
- # If elt is last item, remove and return
195
- if len(self.heap) == 1:
196
- self.heap.pop()
197
- return elt
198
- # Replace root with last element
199
- last = self.heap.pop()
200
- self.heap[0] = last
201
- self.position[last] = 0
202
- # Restore invariant by sifting up
203
- self._siftup(0)
204
- # Return smallest element
205
- return elt
206
-
207
- def update(self, elt, new, priority=None):
208
- """Replace an element in the queue with a new one."""
209
- if priority is not None:
210
- new = _HeapElement(priority, new)
211
- # Replace
212
- pos = self.position[elt]
213
- self.heap[pos] = new
214
- del self.position[elt]
215
- self.position[new] = pos
216
- # Restore invariant by sifting up
217
- self._siftup(pos)
218
-
219
- def remove(self, elt):
220
- """Remove an element from the queue."""
221
- # Find and remove element
222
- try:
223
- pos = self.position[elt]
224
- del self.position[elt]
225
- except KeyError:
226
- # Not in queue
227
- raise
228
- # If elt is last item, remove and return
229
- if pos == len(self.heap) - 1:
230
- self.heap.pop()
231
- return
232
- # Replace elt with last element
233
- last = self.heap.pop()
234
- self.heap[pos] = last
235
- self.position[last] = pos
236
- # Restore invariant by sifting up
237
- self._siftup(pos)
238
-
239
- def _siftup(self, pos):
240
- """Move smaller child up until hitting a leaf.
241
-
242
- Built to mimic code for heapq._siftup
243
- only updating position dict too.
244
- """
245
- heap, position = self.heap, self.position
246
- end_pos = len(heap)
247
- startpos = pos
248
- newitem = heap[pos]
249
- # Shift up the smaller child until hitting a leaf
250
- child_pos = (pos << 1) + 1 # start with leftmost child position
251
- while child_pos < end_pos:
252
- # Set child_pos to index of smaller child.
253
- child = heap[child_pos]
254
- right_pos = child_pos + 1
255
- if right_pos < end_pos:
256
- right = heap[right_pos]
257
- if not child < right:
258
- child = right
259
- child_pos = right_pos
260
- # Move the smaller child up.
261
- heap[pos] = child
262
- position[child] = pos
263
- pos = child_pos
264
- child_pos = (pos << 1) + 1
265
- # pos is a leaf position. Put newitem there, and bubble it up
266
- # to its final resting place (by sifting its parents down).
267
- while pos > 0:
268
- parent_pos = (pos - 1) >> 1
269
- parent = heap[parent_pos]
270
- if not newitem < parent:
271
- break
272
- heap[pos] = parent
273
- position[parent] = pos
274
- pos = parent_pos
275
- heap[pos] = newitem
276
- position[newitem] = pos
277
-
278
- def _siftdown(self, start_pos, pos):
279
- """Restore invariant. keep swapping with parent until smaller.
280
-
281
- Built to mimic code for heapq._siftdown
282
- only updating position dict too.
283
- """
284
- heap, position = self.heap, self.position
285
- newitem = heap[pos]
286
- # Follow the path to the root, moving parents down until finding a place
287
- # newitem fits.
288
- while pos > start_pos:
289
- parent_pos = (pos - 1) >> 1
290
- parent = heap[parent_pos]
291
- if not newitem < parent:
292
- break
293
- heap[pos] = parent
294
- position[parent] = pos
295
- pos = parent_pos
296
- heap[pos] = newitem
297
- position[newitem] = pos