okstra 0.130.4 → 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.
- package/README.md +0 -1
- package/docs/architecture.md +2 -2
- package/docs/cli.md +1 -1
- package/docs/for-ai/README.md +0 -2
- package/docs/for-ai/skills/okstra-run.md +13 -2
- package/docs/for-ai/skills/okstra-setup.md +4 -1
- package/docs/project-structure-overview.md +5 -4
- package/docs/task-process/implementation-planning.md +13 -0
- package/docs/task-process/implementation.md +17 -2
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/report-writer-worker.md +7 -0
- package/runtime/bin/lib/okstra/usage.sh +4 -4
- package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
- package/runtime/prompts/lead/plan-body-verification.md +26 -5
- package/runtime/prompts/lead/report-writer.md +6 -2
- package/runtime/prompts/profiles/_common-contract.md +2 -1
- package/runtime/prompts/profiles/_implementation-deliverable.md +6 -1
- package/runtime/prompts/profiles/_implementation-executor.md +2 -2
- package/runtime/prompts/profiles/_implementation-verifier.md +33 -10
- package/runtime/prompts/profiles/final-verification.md +21 -6
- package/runtime/prompts/profiles/implementation-planning.md +16 -4
- package/runtime/python/okstra_ctl/codex_dispatch.py +31 -0
- package/runtime/python/okstra_ctl/conformance.py +49 -11
- package/runtime/python/okstra_ctl/report_finalize.py +52 -1
- package/runtime/python/okstra_ctl/run.py +15 -3
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +14 -6
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +19 -1
- package/runtime/python/okstra_vendor/__init__.py +0 -44
- package/runtime/schemas/final-report-v1.0.schema.json +99 -5
- package/runtime/skills/okstra-run/SKILL.md +11 -4
- package/runtime/skills/okstra-setup/SKILL.md +3 -2
- package/runtime/skills/okstra-setup/references/project-config.md +16 -7
- package/runtime/templates/reports/final-report.template.md +15 -9
- package/runtime/templates/reports/i18n/en.json +1 -0
- package/runtime/templates/reports/i18n/ko.json +1 -0
- package/runtime/validators/lib/fixtures.sh +6 -0
- package/runtime/validators/validate-run.py +1722 -98
- package/src/cli-registry.mjs +0 -7
- package/src/commands/lifecycle/doctor.mjs +0 -9
- package/src/lib/skill-catalog.mjs +0 -1
- package/docs/for-ai/skills/okstra-graphify.md +0 -64
- package/runtime/python/okstra_ctl/graphify_cmd.py +0 -225
- package/runtime/python/okstra_vendor/graphify/.vendored-version +0 -1
- package/runtime/python/okstra_vendor/graphify/__init__.py +0 -28
- package/runtime/python/okstra_vendor/graphify/__main__.py +0 -1371
- package/runtime/python/okstra_vendor/graphify/analyze.py +0 -540
- package/runtime/python/okstra_vendor/graphify/benchmark.py +0 -129
- package/runtime/python/okstra_vendor/graphify/build.py +0 -107
- package/runtime/python/okstra_vendor/graphify/cache.py +0 -169
- package/runtime/python/okstra_vendor/graphify/cluster.py +0 -137
- package/runtime/python/okstra_vendor/graphify/detect.py +0 -510
- package/runtime/python/okstra_vendor/graphify/export.py +0 -1014
- package/runtime/python/okstra_vendor/graphify/extract.py +0 -3277
- package/runtime/python/okstra_vendor/graphify/hooks.py +0 -220
- package/runtime/python/okstra_vendor/graphify/ingest.py +0 -297
- package/runtime/python/okstra_vendor/graphify/manifest.py +0 -4
- package/runtime/python/okstra_vendor/graphify/report.py +0 -175
- package/runtime/python/okstra_vendor/graphify/security.py +0 -203
- package/runtime/python/okstra_vendor/graphify/serve.py +0 -373
- package/runtime/python/okstra_vendor/graphify/skill-aider.md +0 -1184
- package/runtime/python/okstra_vendor/graphify/skill-claw.md +0 -1184
- package/runtime/python/okstra_vendor/graphify/skill-codex.md +0 -1242
- package/runtime/python/okstra_vendor/graphify/skill-copilot.md +0 -1268
- package/runtime/python/okstra_vendor/graphify/skill-droid.md +0 -1239
- package/runtime/python/okstra_vendor/graphify/skill-kiro.md +0 -1183
- package/runtime/python/okstra_vendor/graphify/skill-opencode.md +0 -1238
- package/runtime/python/okstra_vendor/graphify/skill-trae.md +0 -1208
- package/runtime/python/okstra_vendor/graphify/skill-vscode.md +0 -253
- package/runtime/python/okstra_vendor/graphify/skill-windows.md +0 -1245
- package/runtime/python/okstra_vendor/graphify/skill.md +0 -1319
- package/runtime/python/okstra_vendor/graphify/transcribe.py +0 -182
- package/runtime/python/okstra_vendor/graphify/validate.py +0 -72
- package/runtime/python/okstra_vendor/graphify/watch.py +0 -188
- package/runtime/python/okstra_vendor/graphify/wiki.py +0 -214
- package/runtime/python/okstra_vendor/networkx/__init__.py +0 -62
- package/runtime/python/okstra_vendor/networkx/algorithms/__init__.py +0 -134
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/__init__.py +0 -26
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clique.py +0 -259
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clustering_coefficient.py +0 -71
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/connectivity.py +0 -412
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/density.py +0 -396
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/distance_measures.py +0 -150
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/dominating_set.py +0 -149
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/kcomponents.py +0 -369
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/matching.py +0 -44
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/maxcut.py +0 -143
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/ramsey.py +0 -53
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/steinertree.py +0 -265
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/traveling_salesman.py +0 -1508
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/treewidth.py +0 -255
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/vertex_cover.py +0 -83
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/__init__.py +0 -5
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/connectivity.py +0 -122
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/correlation.py +0 -302
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/mixing.py +0 -255
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/neighbor_degree.py +0 -160
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/pairs.py +0 -127
- package/runtime/python/okstra_vendor/networkx/algorithms/asteroidal.py +0 -164
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/__init__.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/basic.py +0 -322
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/centrality.py +0 -290
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/cluster.py +0 -289
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/covering.py +0 -57
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/edgelist.py +0 -360
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/extendability.py +0 -105
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/generators.py +0 -603
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/link_analysis.py +0 -316
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matching.py +0 -590
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matrix.py +0 -232
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/projection.py +0 -526
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/redundancy.py +0 -112
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/spectral.py +0 -69
- package/runtime/python/okstra_vendor/networkx/algorithms/boundary.py +0 -168
- package/runtime/python/okstra_vendor/networkx/algorithms/bridges.py +0 -205
- package/runtime/python/okstra_vendor/networkx/algorithms/broadcasting.py +0 -164
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/__init__.py +0 -20
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness.py +0 -591
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness_subset.py +0 -236
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/closeness.py +0 -282
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness.py +0 -364
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness_subset.py +0 -227
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_closeness.py +0 -96
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/degree_alg.py +0 -150
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/dispersion.py +0 -107
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/eigenvector.py +0 -357
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/flow_matrix.py +0 -130
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/group.py +0 -787
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/harmonic.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/katz.py +0 -331
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/laplacian.py +0 -150
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/load.py +0 -200
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/percolation.py +0 -128
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/reaching.py +0 -209
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/second_order.py +0 -141
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/subgraph_alg.py +0 -361
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/trophic.py +0 -181
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/voterank_alg.py +0 -95
- package/runtime/python/okstra_vendor/networkx/algorithms/chains.py +0 -172
- package/runtime/python/okstra_vendor/networkx/algorithms/chordal.py +0 -443
- package/runtime/python/okstra_vendor/networkx/algorithms/clique.py +0 -818
- package/runtime/python/okstra_vendor/networkx/algorithms/cluster.py +0 -732
- package/runtime/python/okstra_vendor/networkx/algorithms/coloring/__init__.py +0 -4
- package/runtime/python/okstra_vendor/networkx/algorithms/coloring/equitable_coloring.py +0 -505
- package/runtime/python/okstra_vendor/networkx/algorithms/coloring/greedy_coloring.py +0 -565
- package/runtime/python/okstra_vendor/networkx/algorithms/communicability_alg.py +0 -163
- package/runtime/python/okstra_vendor/networkx/algorithms/community/__init__.py +0 -28
- package/runtime/python/okstra_vendor/networkx/algorithms/community/asyn_fluid.py +0 -153
- package/runtime/python/okstra_vendor/networkx/algorithms/community/bipartitions.py +0 -354
- package/runtime/python/okstra_vendor/networkx/algorithms/community/centrality.py +0 -171
- package/runtime/python/okstra_vendor/networkx/algorithms/community/community_utils.py +0 -30
- package/runtime/python/okstra_vendor/networkx/algorithms/community/divisive.py +0 -216
- package/runtime/python/okstra_vendor/networkx/algorithms/community/kclique.py +0 -79
- package/runtime/python/okstra_vendor/networkx/algorithms/community/label_propagation.py +0 -338
- package/runtime/python/okstra_vendor/networkx/algorithms/community/leiden.py +0 -162
- package/runtime/python/okstra_vendor/networkx/algorithms/community/local.py +0 -220
- package/runtime/python/okstra_vendor/networkx/algorithms/community/louvain.py +0 -384
- package/runtime/python/okstra_vendor/networkx/algorithms/community/lukes.py +0 -227
- package/runtime/python/okstra_vendor/networkx/algorithms/community/modularity_max.py +0 -452
- package/runtime/python/okstra_vendor/networkx/algorithms/community/quality.py +0 -347
- package/runtime/python/okstra_vendor/networkx/algorithms/components/__init__.py +0 -6
- package/runtime/python/okstra_vendor/networkx/algorithms/components/attracting.py +0 -115
- package/runtime/python/okstra_vendor/networkx/algorithms/components/biconnected.py +0 -394
- package/runtime/python/okstra_vendor/networkx/algorithms/components/connected.py +0 -282
- package/runtime/python/okstra_vendor/networkx/algorithms/components/semiconnected.py +0 -71
- package/runtime/python/okstra_vendor/networkx/algorithms/components/strongly_connected.py +0 -359
- package/runtime/python/okstra_vendor/networkx/algorithms/components/weakly_connected.py +0 -196
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/__init__.py +0 -11
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/connectivity.py +0 -811
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/cuts.py +0 -616
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/disjoint_paths.py +0 -408
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_augmentation.py +0 -1270
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_kcomponents.py +0 -592
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcomponents.py +0 -220
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcutsets.py +0 -235
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/stoerwagner.py +0 -152
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/utils.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/core.py +0 -588
- package/runtime/python/okstra_vendor/networkx/algorithms/covering.py +0 -142
- package/runtime/python/okstra_vendor/networkx/algorithms/cuts.py +0 -416
- package/runtime/python/okstra_vendor/networkx/algorithms/cycles.py +0 -1234
- package/runtime/python/okstra_vendor/networkx/algorithms/d_separation.py +0 -677
- package/runtime/python/okstra_vendor/networkx/algorithms/dag.py +0 -1392
- package/runtime/python/okstra_vendor/networkx/algorithms/distance_measures.py +0 -1095
- package/runtime/python/okstra_vendor/networkx/algorithms/distance_regular.py +0 -272
- package/runtime/python/okstra_vendor/networkx/algorithms/dominance.py +0 -142
- package/runtime/python/okstra_vendor/networkx/algorithms/dominating.py +0 -268
- package/runtime/python/okstra_vendor/networkx/algorithms/efficiency_measures.py +0 -167
- package/runtime/python/okstra_vendor/networkx/algorithms/euler.py +0 -470
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/__init__.py +0 -11
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/boykovkolmogorov.py +0 -370
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/capacityscaling.py +0 -407
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/dinitz_alg.py +0 -238
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/edmondskarp.py +0 -241
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/gomory_hu.py +0 -178
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/maxflow.py +0 -611
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/mincost.py +0 -356
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/networksimplex.py +0 -662
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/preflowpush.py +0 -425
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/shortestaugmentingpath.py +0 -300
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/utils.py +0 -194
- package/runtime/python/okstra_vendor/networkx/algorithms/graph_hashing.py +0 -435
- package/runtime/python/okstra_vendor/networkx/algorithms/graphical.py +0 -483
- package/runtime/python/okstra_vendor/networkx/algorithms/hierarchy.py +0 -57
- package/runtime/python/okstra_vendor/networkx/algorithms/hybrid.py +0 -196
- package/runtime/python/okstra_vendor/networkx/algorithms/isolate.py +0 -107
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/__init__.py +0 -7
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/ismags.py +0 -1306
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorph.py +0 -336
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorphvf2.py +0 -1262
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/matchhelpers.py +0 -352
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/temporalisomorphvf2.py +0 -308
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tree_isomorphism.py +0 -264
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2pp.py +0 -1102
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2userfunc.py +0 -192
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/__init__.py +0 -2
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/hits_alg.py +0 -337
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/pagerank_alg.py +0 -498
- package/runtime/python/okstra_vendor/networkx/algorithms/link_prediction.py +0 -687
- package/runtime/python/okstra_vendor/networkx/algorithms/lowest_common_ancestors.py +0 -280
- package/runtime/python/okstra_vendor/networkx/algorithms/matching.py +0 -1148
- package/runtime/python/okstra_vendor/networkx/algorithms/minors/__init__.py +0 -27
- package/runtime/python/okstra_vendor/networkx/algorithms/minors/contraction.py +0 -738
- package/runtime/python/okstra_vendor/networkx/algorithms/mis.py +0 -78
- package/runtime/python/okstra_vendor/networkx/algorithms/moral.py +0 -59
- package/runtime/python/okstra_vendor/networkx/algorithms/node_classification.py +0 -219
- package/runtime/python/okstra_vendor/networkx/algorithms/non_randomness.py +0 -155
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/__init__.py +0 -4
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/all.py +0 -324
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/binary.py +0 -468
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/product.py +0 -633
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/unary.py +0 -77
- package/runtime/python/okstra_vendor/networkx/algorithms/perfect_graph.py +0 -73
- package/runtime/python/okstra_vendor/networkx/algorithms/planar_drawing.py +0 -464
- package/runtime/python/okstra_vendor/networkx/algorithms/planarity.py +0 -1463
- package/runtime/python/okstra_vendor/networkx/algorithms/polynomials.py +0 -306
- package/runtime/python/okstra_vendor/networkx/algorithms/reciprocity.py +0 -98
- package/runtime/python/okstra_vendor/networkx/algorithms/regular.py +0 -167
- package/runtime/python/okstra_vendor/networkx/algorithms/richclub.py +0 -138
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/__init__.py +0 -5
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/astar.py +0 -239
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/dense.py +0 -264
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/generic.py +0 -716
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/unweighted.py +0 -625
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/weighted.py +0 -2542
- package/runtime/python/okstra_vendor/networkx/algorithms/similarity.py +0 -2107
- package/runtime/python/okstra_vendor/networkx/algorithms/simple_paths.py +0 -966
- package/runtime/python/okstra_vendor/networkx/algorithms/smallworld.py +0 -404
- package/runtime/python/okstra_vendor/networkx/algorithms/smetric.py +0 -30
- package/runtime/python/okstra_vendor/networkx/algorithms/sparsifiers.py +0 -296
- package/runtime/python/okstra_vendor/networkx/algorithms/structuralholes.py +0 -374
- package/runtime/python/okstra_vendor/networkx/algorithms/summarization.py +0 -564
- package/runtime/python/okstra_vendor/networkx/algorithms/swap.py +0 -406
- package/runtime/python/okstra_vendor/networkx/algorithms/threshold.py +0 -981
- package/runtime/python/okstra_vendor/networkx/algorithms/time_dependent.py +0 -142
- package/runtime/python/okstra_vendor/networkx/algorithms/tournament.py +0 -406
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/__init__.py +0 -5
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/beamsearch.py +0 -90
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/breadth_first_search.py +0 -576
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/depth_first_search.py +0 -529
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgebfs.py +0 -185
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgedfs.py +0 -182
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/__init__.py +0 -7
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/branchings.py +0 -1042
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/coding.py +0 -413
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/decomposition.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/distance_measures.py +0 -219
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/mst.py +0 -1281
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/operations.py +0 -106
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/recognition.py +0 -273
- package/runtime/python/okstra_vendor/networkx/algorithms/triads.py +0 -500
- package/runtime/python/okstra_vendor/networkx/algorithms/vitality.py +0 -76
- package/runtime/python/okstra_vendor/networkx/algorithms/voronoi.py +0 -86
- package/runtime/python/okstra_vendor/networkx/algorithms/walks.py +0 -77
- package/runtime/python/okstra_vendor/networkx/algorithms/wiener.py +0 -278
- package/runtime/python/okstra_vendor/networkx/classes/__init__.py +0 -13
- package/runtime/python/okstra_vendor/networkx/classes/coreviews.py +0 -435
- package/runtime/python/okstra_vendor/networkx/classes/digraph.py +0 -1363
- package/runtime/python/okstra_vendor/networkx/classes/filters.py +0 -95
- package/runtime/python/okstra_vendor/networkx/classes/function.py +0 -1549
- package/runtime/python/okstra_vendor/networkx/classes/graph.py +0 -2082
- package/runtime/python/okstra_vendor/networkx/classes/graphviews.py +0 -269
- package/runtime/python/okstra_vendor/networkx/classes/multidigraph.py +0 -977
- package/runtime/python/okstra_vendor/networkx/classes/multigraph.py +0 -1294
- package/runtime/python/okstra_vendor/networkx/classes/reportviews.py +0 -1447
- package/runtime/python/okstra_vendor/networkx/convert.py +0 -502
- package/runtime/python/okstra_vendor/networkx/convert_matrix.py +0 -1314
- package/runtime/python/okstra_vendor/networkx/drawing/__init__.py +0 -7
- package/runtime/python/okstra_vendor/networkx/drawing/layout.py +0 -2036
- package/runtime/python/okstra_vendor/networkx/drawing/nx_agraph.py +0 -470
- package/runtime/python/okstra_vendor/networkx/drawing/nx_latex.py +0 -570
- package/runtime/python/okstra_vendor/networkx/drawing/nx_pydot.py +0 -361
- package/runtime/python/okstra_vendor/networkx/drawing/nx_pylab.py +0 -2978
- package/runtime/python/okstra_vendor/networkx/exception.py +0 -131
- package/runtime/python/okstra_vendor/networkx/generators/__init__.py +0 -34
- package/runtime/python/okstra_vendor/networkx/generators/atlas.dat.gz +0 -0
- package/runtime/python/okstra_vendor/networkx/generators/atlas.py +0 -227
- package/runtime/python/okstra_vendor/networkx/generators/classic.py +0 -1091
- package/runtime/python/okstra_vendor/networkx/generators/cographs.py +0 -68
- package/runtime/python/okstra_vendor/networkx/generators/community.py +0 -1070
- package/runtime/python/okstra_vendor/networkx/generators/degree_seq.py +0 -886
- package/runtime/python/okstra_vendor/networkx/generators/directed.py +0 -572
- package/runtime/python/okstra_vendor/networkx/generators/duplication.py +0 -174
- package/runtime/python/okstra_vendor/networkx/generators/ego.py +0 -66
- package/runtime/python/okstra_vendor/networkx/generators/expanders.py +0 -499
- package/runtime/python/okstra_vendor/networkx/generators/geometric.py +0 -1037
- package/runtime/python/okstra_vendor/networkx/generators/harary_graph.py +0 -163
- package/runtime/python/okstra_vendor/networkx/generators/internet_as_graphs.py +0 -443
- package/runtime/python/okstra_vendor/networkx/generators/intersection.py +0 -125
- package/runtime/python/okstra_vendor/networkx/generators/interval_graph.py +0 -70
- package/runtime/python/okstra_vendor/networkx/generators/joint_degree_seq.py +0 -664
- package/runtime/python/okstra_vendor/networkx/generators/lattice.py +0 -405
- package/runtime/python/okstra_vendor/networkx/generators/line.py +0 -501
- package/runtime/python/okstra_vendor/networkx/generators/mycielski.py +0 -110
- package/runtime/python/okstra_vendor/networkx/generators/nonisomorphic_trees.py +0 -259
- package/runtime/python/okstra_vendor/networkx/generators/random_clustered.py +0 -117
- package/runtime/python/okstra_vendor/networkx/generators/random_graphs.py +0 -1416
- package/runtime/python/okstra_vendor/networkx/generators/small.py +0 -1070
- package/runtime/python/okstra_vendor/networkx/generators/social.py +0 -554
- package/runtime/python/okstra_vendor/networkx/generators/spectral_graph_forge.py +0 -120
- package/runtime/python/okstra_vendor/networkx/generators/stochastic.py +0 -54
- package/runtime/python/okstra_vendor/networkx/generators/sudoku.py +0 -131
- package/runtime/python/okstra_vendor/networkx/generators/time_series.py +0 -74
- package/runtime/python/okstra_vendor/networkx/generators/trees.py +0 -1070
- package/runtime/python/okstra_vendor/networkx/generators/triads.py +0 -94
- package/runtime/python/okstra_vendor/networkx/lazy_imports.py +0 -188
- package/runtime/python/okstra_vendor/networkx/linalg/__init__.py +0 -13
- package/runtime/python/okstra_vendor/networkx/linalg/algebraicconnectivity.py +0 -650
- package/runtime/python/okstra_vendor/networkx/linalg/attrmatrix.py +0 -466
- package/runtime/python/okstra_vendor/networkx/linalg/bethehessianmatrix.py +0 -77
- package/runtime/python/okstra_vendor/networkx/linalg/graphmatrix.py +0 -168
- package/runtime/python/okstra_vendor/networkx/linalg/laplacianmatrix.py +0 -512
- package/runtime/python/okstra_vendor/networkx/linalg/modularitymatrix.py +0 -166
- package/runtime/python/okstra_vendor/networkx/linalg/spectrum.py +0 -186
- package/runtime/python/okstra_vendor/networkx/readwrite/__init__.py +0 -17
- package/runtime/python/okstra_vendor/networkx/readwrite/adjlist.py +0 -330
- package/runtime/python/okstra_vendor/networkx/readwrite/edgelist.py +0 -489
- package/runtime/python/okstra_vendor/networkx/readwrite/gexf.py +0 -1084
- package/runtime/python/okstra_vendor/networkx/readwrite/gml.py +0 -879
- package/runtime/python/okstra_vendor/networkx/readwrite/graph6.py +0 -427
- package/runtime/python/okstra_vendor/networkx/readwrite/graphml.py +0 -1053
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/__init__.py +0 -19
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/adjacency.py +0 -156
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/cytoscape.py +0 -190
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/node_link.py +0 -261
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tree.py +0 -137
- package/runtime/python/okstra_vendor/networkx/readwrite/leda.py +0 -108
- package/runtime/python/okstra_vendor/networkx/readwrite/multiline_adjlist.py +0 -393
- package/runtime/python/okstra_vendor/networkx/readwrite/p2g.py +0 -113
- package/runtime/python/okstra_vendor/networkx/readwrite/pajek.py +0 -286
- package/runtime/python/okstra_vendor/networkx/readwrite/sparse6.py +0 -379
- package/runtime/python/okstra_vendor/networkx/readwrite/text.py +0 -851
- package/runtime/python/okstra_vendor/networkx/relabel.py +0 -285
- package/runtime/python/okstra_vendor/networkx/utils/__init__.py +0 -8
- package/runtime/python/okstra_vendor/networkx/utils/backends.py +0 -2171
- package/runtime/python/okstra_vendor/networkx/utils/configs.py +0 -396
- package/runtime/python/okstra_vendor/networkx/utils/decorators.py +0 -1233
- package/runtime/python/okstra_vendor/networkx/utils/heaps.py +0 -338
- package/runtime/python/okstra_vendor/networkx/utils/mapped_queue.py +0 -297
- package/runtime/python/okstra_vendor/networkx/utils/misc.py +0 -703
- package/runtime/python/okstra_vendor/networkx/utils/random_sequence.py +0 -198
- package/runtime/python/okstra_vendor/networkx/utils/rcm.py +0 -159
- package/runtime/python/okstra_vendor/networkx/utils/union_find.py +0 -106
- package/runtime/skills/okstra-graphify/SKILL.md +0 -169
- package/src/commands/graphify.mjs +0 -32
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
"""Operations on trees."""
|
|
2
|
-
|
|
3
|
-
from functools import partial
|
|
4
|
-
from itertools import accumulate, chain
|
|
5
|
-
|
|
6
|
-
import networkx as nx
|
|
7
|
-
|
|
8
|
-
__all__ = ["join_trees"]
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# Argument types don't match dispatching, but allow manual selection of backend
|
|
12
|
-
@nx._dispatchable(graphs=None, returns_graph=True)
|
|
13
|
-
def join_trees(rooted_trees, *, label_attribute=None, first_label=0):
|
|
14
|
-
"""Returns a new rooted tree made by joining `rooted_trees`
|
|
15
|
-
|
|
16
|
-
Constructs a new tree by joining each tree in `rooted_trees`.
|
|
17
|
-
A new root node is added and connected to each of the roots
|
|
18
|
-
of the input trees. While copying the nodes from the trees,
|
|
19
|
-
relabeling to integers occurs. If the `label_attribute` is provided,
|
|
20
|
-
the old node labels will be stored in the new tree under this attribute.
|
|
21
|
-
|
|
22
|
-
Parameters
|
|
23
|
-
----------
|
|
24
|
-
rooted_trees : list
|
|
25
|
-
A list of pairs in which each left element is a NetworkX graph
|
|
26
|
-
object representing a tree and each right element is the root
|
|
27
|
-
node of that tree. The nodes of these trees will be relabeled to
|
|
28
|
-
integers.
|
|
29
|
-
|
|
30
|
-
label_attribute : str
|
|
31
|
-
If provided, the old node labels will be stored in the new tree
|
|
32
|
-
under this node attribute. If not provided, the original labels
|
|
33
|
-
of the nodes in the input trees are not stored.
|
|
34
|
-
|
|
35
|
-
first_label : int, optional (default=0)
|
|
36
|
-
Specifies the label for the new root node. If provided, the root node of the joined tree
|
|
37
|
-
will have this label. If not provided, the root node will default to a label of 0.
|
|
38
|
-
|
|
39
|
-
Returns
|
|
40
|
-
-------
|
|
41
|
-
NetworkX graph
|
|
42
|
-
The rooted tree resulting from joining the provided `rooted_trees`. The new tree has a root node
|
|
43
|
-
labeled as specified by `first_label` (defaulting to 0 if not provided). Subtrees from the input
|
|
44
|
-
`rooted_trees` are attached to this new root node. Each non-root node, if the `label_attribute`
|
|
45
|
-
is provided, has an attribute that indicates the original label of the node in the input tree.
|
|
46
|
-
|
|
47
|
-
Notes
|
|
48
|
-
-----
|
|
49
|
-
Trees are stored in NetworkX as NetworkX Graphs. There is no specific
|
|
50
|
-
enforcement of the fact that these are trees. Testing for each tree
|
|
51
|
-
can be done using :func:`networkx.is_tree`.
|
|
52
|
-
|
|
53
|
-
Graph, edge, and node attributes are propagated from the given
|
|
54
|
-
rooted trees to the created tree. If there are any overlapping graph
|
|
55
|
-
attributes, those from later trees will overwrite those from earlier
|
|
56
|
-
trees in the tuple of positional arguments.
|
|
57
|
-
|
|
58
|
-
Examples
|
|
59
|
-
--------
|
|
60
|
-
Join two full balanced binary trees of height *h* to get a full
|
|
61
|
-
balanced binary tree of depth *h* + 1::
|
|
62
|
-
|
|
63
|
-
>>> h = 4
|
|
64
|
-
>>> left = nx.balanced_tree(2, h)
|
|
65
|
-
>>> right = nx.balanced_tree(2, h)
|
|
66
|
-
>>> joined_tree = nx.join_trees([(left, 0), (right, 0)])
|
|
67
|
-
>>> nx.is_isomorphic(joined_tree, nx.balanced_tree(2, h + 1))
|
|
68
|
-
True
|
|
69
|
-
|
|
70
|
-
"""
|
|
71
|
-
if not rooted_trees:
|
|
72
|
-
return nx.empty_graph(1)
|
|
73
|
-
|
|
74
|
-
# Unzip the zipped list of (tree, root) pairs.
|
|
75
|
-
trees, roots = zip(*rooted_trees)
|
|
76
|
-
|
|
77
|
-
# The join of the trees has the same type as the type of the first tree.
|
|
78
|
-
R = type(trees[0])()
|
|
79
|
-
|
|
80
|
-
lengths = (len(tree) for tree in trees[:-1])
|
|
81
|
-
first_labels = list(accumulate(lengths, initial=first_label + 1))
|
|
82
|
-
|
|
83
|
-
new_roots = []
|
|
84
|
-
for tree, root, first_node in zip(trees, roots, first_labels):
|
|
85
|
-
new_root = first_node + list(tree.nodes()).index(root)
|
|
86
|
-
new_roots.append(new_root)
|
|
87
|
-
|
|
88
|
-
# Relabel the nodes so that their union is the integers starting at first_label.
|
|
89
|
-
relabel = partial(
|
|
90
|
-
nx.convert_node_labels_to_integers, label_attribute=label_attribute
|
|
91
|
-
)
|
|
92
|
-
new_trees = [
|
|
93
|
-
relabel(tree, first_label=first_label)
|
|
94
|
-
for tree, first_label in zip(trees, first_labels)
|
|
95
|
-
]
|
|
96
|
-
|
|
97
|
-
# Add all sets of nodes and edges, attributes
|
|
98
|
-
for tree in new_trees:
|
|
99
|
-
R.update(tree)
|
|
100
|
-
|
|
101
|
-
# Finally, join the subtrees at the root. We know first_label is unused by
|
|
102
|
-
# the way we relabeled the subtrees.
|
|
103
|
-
R.add_node(first_label)
|
|
104
|
-
R.add_edges_from((first_label, root) for root in new_roots)
|
|
105
|
-
|
|
106
|
-
return R
|
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Recognition Tests
|
|
3
|
-
=================
|
|
4
|
-
|
|
5
|
-
A *forest* is an acyclic, undirected graph, and a *tree* is a connected forest.
|
|
6
|
-
Depending on the subfield, there are various conventions for generalizing these
|
|
7
|
-
definitions to directed graphs.
|
|
8
|
-
|
|
9
|
-
In one convention, directed variants of forest and tree are defined in an
|
|
10
|
-
identical manner, except that the direction of the edges is ignored. In effect,
|
|
11
|
-
each directed edge is treated as a single undirected edge. Then, additional
|
|
12
|
-
restrictions are imposed to define *branchings* and *arborescences*.
|
|
13
|
-
|
|
14
|
-
In another convention, directed variants of forest and tree correspond to
|
|
15
|
-
the previous convention's branchings and arborescences, respectively. Then two
|
|
16
|
-
new terms, *polyforest* and *polytree*, are defined to correspond to the other
|
|
17
|
-
convention's forest and tree.
|
|
18
|
-
|
|
19
|
-
Summarizing::
|
|
20
|
-
|
|
21
|
-
+-----------------------------+
|
|
22
|
-
| Convention A | Convention B |
|
|
23
|
-
+=============================+
|
|
24
|
-
| forest | polyforest |
|
|
25
|
-
| tree | polytree |
|
|
26
|
-
| branching | forest |
|
|
27
|
-
| arborescence | tree |
|
|
28
|
-
+-----------------------------+
|
|
29
|
-
|
|
30
|
-
Each convention has its reasons. The first convention emphasizes definitional
|
|
31
|
-
similarity in that directed forests and trees are only concerned with
|
|
32
|
-
acyclicity and do not have an in-degree constraint, just as their undirected
|
|
33
|
-
counterparts do not. The second convention emphasizes functional similarity
|
|
34
|
-
in the sense that the directed analog of a spanning tree is a spanning
|
|
35
|
-
arborescence. That is, take any spanning tree and choose one node as the root.
|
|
36
|
-
Then every edge is assigned a direction such there is a directed path from the
|
|
37
|
-
root to every other node. The result is a spanning arborescence.
|
|
38
|
-
|
|
39
|
-
NetworkX follows convention "A". Explicitly, these are:
|
|
40
|
-
|
|
41
|
-
undirected forest
|
|
42
|
-
An undirected graph with no undirected cycles.
|
|
43
|
-
|
|
44
|
-
undirected tree
|
|
45
|
-
A connected, undirected forest.
|
|
46
|
-
|
|
47
|
-
directed forest
|
|
48
|
-
A directed graph with no undirected cycles. Equivalently, the underlying
|
|
49
|
-
graph structure (which ignores edge orientations) is an undirected forest.
|
|
50
|
-
In convention B, this is known as a polyforest.
|
|
51
|
-
|
|
52
|
-
directed tree
|
|
53
|
-
A weakly connected, directed forest. Equivalently, the underlying graph
|
|
54
|
-
structure (which ignores edge orientations) is an undirected tree. In
|
|
55
|
-
convention B, this is known as a polytree.
|
|
56
|
-
|
|
57
|
-
branching
|
|
58
|
-
A directed forest with each node having, at most, one parent. So the maximum
|
|
59
|
-
in-degree is equal to 1. In convention B, this is known as a forest.
|
|
60
|
-
|
|
61
|
-
arborescence
|
|
62
|
-
A directed tree with each node having, at most, one parent. So the maximum
|
|
63
|
-
in-degree is equal to 1. In convention B, this is known as a tree.
|
|
64
|
-
|
|
65
|
-
For trees and arborescences, the adjective "spanning" may be added to designate
|
|
66
|
-
that the graph, when considered as a forest/branching, consists of a single
|
|
67
|
-
tree/arborescence that includes all nodes in the graph. It is true, by
|
|
68
|
-
definition, that every tree/arborescence is spanning with respect to the nodes
|
|
69
|
-
that define the tree/arborescence and so, it might seem redundant to introduce
|
|
70
|
-
the notion of "spanning". However, the nodes may represent a subset of
|
|
71
|
-
nodes from a larger graph, and it is in this context that the term "spanning"
|
|
72
|
-
becomes a useful notion.
|
|
73
|
-
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
import networkx as nx
|
|
77
|
-
|
|
78
|
-
__all__ = ["is_arborescence", "is_branching", "is_forest", "is_tree"]
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
@nx.utils.not_implemented_for("undirected")
|
|
82
|
-
@nx._dispatchable
|
|
83
|
-
def is_arborescence(G):
|
|
84
|
-
"""
|
|
85
|
-
Returns True if `G` is an arborescence.
|
|
86
|
-
|
|
87
|
-
An arborescence is a directed tree with maximum in-degree equal to 1.
|
|
88
|
-
|
|
89
|
-
Parameters
|
|
90
|
-
----------
|
|
91
|
-
G : graph
|
|
92
|
-
The graph to test.
|
|
93
|
-
|
|
94
|
-
Returns
|
|
95
|
-
-------
|
|
96
|
-
b : bool
|
|
97
|
-
A boolean that is True if `G` is an arborescence.
|
|
98
|
-
|
|
99
|
-
Examples
|
|
100
|
-
--------
|
|
101
|
-
>>> G = nx.DiGraph([(0, 1), (0, 2), (2, 3), (3, 4)])
|
|
102
|
-
>>> nx.is_arborescence(G)
|
|
103
|
-
True
|
|
104
|
-
>>> G.remove_edge(0, 1)
|
|
105
|
-
>>> G.add_edge(1, 2) # maximum in-degree is 2
|
|
106
|
-
>>> nx.is_arborescence(G)
|
|
107
|
-
False
|
|
108
|
-
|
|
109
|
-
Notes
|
|
110
|
-
-----
|
|
111
|
-
In another convention, an arborescence is known as a *tree*.
|
|
112
|
-
|
|
113
|
-
See Also
|
|
114
|
-
--------
|
|
115
|
-
is_tree
|
|
116
|
-
|
|
117
|
-
"""
|
|
118
|
-
return is_tree(G) and max(d for n, d in G.in_degree()) <= 1
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
@nx.utils.not_implemented_for("undirected")
|
|
122
|
-
@nx._dispatchable
|
|
123
|
-
def is_branching(G):
|
|
124
|
-
"""
|
|
125
|
-
Returns True if `G` is a branching.
|
|
126
|
-
|
|
127
|
-
A branching is a directed forest with maximum in-degree equal to 1.
|
|
128
|
-
|
|
129
|
-
Parameters
|
|
130
|
-
----------
|
|
131
|
-
G : directed graph
|
|
132
|
-
The directed graph to test.
|
|
133
|
-
|
|
134
|
-
Returns
|
|
135
|
-
-------
|
|
136
|
-
b : bool
|
|
137
|
-
A boolean that is True if `G` is a branching.
|
|
138
|
-
|
|
139
|
-
Examples
|
|
140
|
-
--------
|
|
141
|
-
>>> G = nx.DiGraph([(0, 1), (1, 2), (2, 3), (3, 4)])
|
|
142
|
-
>>> nx.is_branching(G)
|
|
143
|
-
True
|
|
144
|
-
>>> G.remove_edge(2, 3)
|
|
145
|
-
>>> G.add_edge(3, 1) # maximum in-degree is 2
|
|
146
|
-
>>> nx.is_branching(G)
|
|
147
|
-
False
|
|
148
|
-
|
|
149
|
-
Notes
|
|
150
|
-
-----
|
|
151
|
-
In another convention, a branching is also known as a *forest*.
|
|
152
|
-
|
|
153
|
-
See Also
|
|
154
|
-
--------
|
|
155
|
-
is_forest
|
|
156
|
-
|
|
157
|
-
"""
|
|
158
|
-
return is_forest(G) and max(d for n, d in G.in_degree()) <= 1
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
@nx._dispatchable
|
|
162
|
-
def is_forest(G):
|
|
163
|
-
"""
|
|
164
|
-
Returns True if `G` is a forest.
|
|
165
|
-
|
|
166
|
-
A forest is a graph with no undirected cycles.
|
|
167
|
-
|
|
168
|
-
For directed graphs, `G` is a forest if the underlying graph is a forest.
|
|
169
|
-
The underlying graph is obtained by treating each directed edge as a single
|
|
170
|
-
undirected edge in a multigraph.
|
|
171
|
-
|
|
172
|
-
Parameters
|
|
173
|
-
----------
|
|
174
|
-
G : graph
|
|
175
|
-
The graph to test.
|
|
176
|
-
|
|
177
|
-
Returns
|
|
178
|
-
-------
|
|
179
|
-
b : bool
|
|
180
|
-
A boolean that is True if `G` is a forest.
|
|
181
|
-
|
|
182
|
-
Raises
|
|
183
|
-
------
|
|
184
|
-
NetworkXPointlessConcept
|
|
185
|
-
If `G` is empty.
|
|
186
|
-
|
|
187
|
-
Examples
|
|
188
|
-
--------
|
|
189
|
-
>>> G = nx.Graph()
|
|
190
|
-
>>> G.add_edges_from([(1, 2), (1, 3), (2, 4), (2, 5)])
|
|
191
|
-
>>> nx.is_forest(G)
|
|
192
|
-
True
|
|
193
|
-
>>> G.add_edge(4, 1)
|
|
194
|
-
>>> nx.is_forest(G)
|
|
195
|
-
False
|
|
196
|
-
|
|
197
|
-
Notes
|
|
198
|
-
-----
|
|
199
|
-
In another convention, a directed forest is known as a *polyforest* and
|
|
200
|
-
then *forest* corresponds to a *branching*.
|
|
201
|
-
|
|
202
|
-
See Also
|
|
203
|
-
--------
|
|
204
|
-
is_branching
|
|
205
|
-
|
|
206
|
-
"""
|
|
207
|
-
if len(G) == 0:
|
|
208
|
-
raise nx.exception.NetworkXPointlessConcept("G has no nodes.")
|
|
209
|
-
|
|
210
|
-
if G.is_directed():
|
|
211
|
-
components = (G.subgraph(c) for c in nx.weakly_connected_components(G))
|
|
212
|
-
else:
|
|
213
|
-
components = (G.subgraph(c) for c in nx.connected_components(G))
|
|
214
|
-
|
|
215
|
-
return all(len(c) - 1 == c.number_of_edges() for c in components)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
@nx._dispatchable
|
|
219
|
-
def is_tree(G):
|
|
220
|
-
"""
|
|
221
|
-
Returns True if `G` is a tree.
|
|
222
|
-
|
|
223
|
-
A tree is a connected graph with no undirected cycles.
|
|
224
|
-
|
|
225
|
-
For directed graphs, `G` is a tree if the underlying graph is a tree. The
|
|
226
|
-
underlying graph is obtained by treating each directed edge as a single
|
|
227
|
-
undirected edge in a multigraph.
|
|
228
|
-
|
|
229
|
-
Parameters
|
|
230
|
-
----------
|
|
231
|
-
G : graph
|
|
232
|
-
The graph to test.
|
|
233
|
-
|
|
234
|
-
Returns
|
|
235
|
-
-------
|
|
236
|
-
b : bool
|
|
237
|
-
A boolean that is True if `G` is a tree.
|
|
238
|
-
|
|
239
|
-
Raises
|
|
240
|
-
------
|
|
241
|
-
NetworkXPointlessConcept
|
|
242
|
-
If `G` is empty.
|
|
243
|
-
|
|
244
|
-
Examples
|
|
245
|
-
--------
|
|
246
|
-
>>> G = nx.Graph()
|
|
247
|
-
>>> G.add_edges_from([(1, 2), (1, 3), (2, 4), (2, 5)])
|
|
248
|
-
>>> nx.is_tree(G) # n-1 edges
|
|
249
|
-
True
|
|
250
|
-
>>> G.add_edge(3, 4)
|
|
251
|
-
>>> nx.is_tree(G) # n edges
|
|
252
|
-
False
|
|
253
|
-
|
|
254
|
-
Notes
|
|
255
|
-
-----
|
|
256
|
-
In another convention, a directed tree is known as a *polytree* and then
|
|
257
|
-
*tree* corresponds to an *arborescence*.
|
|
258
|
-
|
|
259
|
-
See Also
|
|
260
|
-
--------
|
|
261
|
-
is_arborescence
|
|
262
|
-
|
|
263
|
-
"""
|
|
264
|
-
if len(G) == 0:
|
|
265
|
-
raise nx.exception.NetworkXPointlessConcept("G has no nodes.")
|
|
266
|
-
|
|
267
|
-
if G.is_directed():
|
|
268
|
-
is_connected = nx.is_weakly_connected
|
|
269
|
-
else:
|
|
270
|
-
is_connected = nx.is_connected
|
|
271
|
-
|
|
272
|
-
# A connected graph with no cycles has n-1 edges.
|
|
273
|
-
return len(G) - 1 == G.number_of_edges() and is_connected(G)
|