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,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