py3plex 2.0.1__tar.gz → 2.0.8__tar.gz

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 (955) hide show
  1. {py3plex-2.0.1/py3plex.egg-info → py3plex-2.0.8}/PKG-INFO +7 -4
  2. {py3plex-2.0.1 → py3plex-2.0.8}/README.md +6 -3
  3. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/__init__.py +3 -2
  4. py3plex-2.0.8/py3plex/_safe_expression.py +101 -0
  5. py3plex-2.0.8/py3plex/_version.py +3 -0
  6. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/autocommunity_executor.py +2 -3
  7. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/community_louvain.py +3 -3
  8. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/label_propagation.py +4 -4
  9. py3plex-2.0.8/py3plex/algorithms/community_detection/mdl_benchmark.py +353 -0
  10. py3plex-2.0.8/py3plex/algorithms/community_detection/multilayer_quality_metrics.py +796 -0
  11. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/multilayer_algorithms/centrality.py +8 -3
  12. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistics/multilayer_statistics.py +5 -3
  13. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/cli.py +577 -54
  14. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/config.py +3 -2
  15. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/multinet.py +58 -51
  16. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/parsers.py +84 -38
  17. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/random_generators.py +1 -0
  18. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/temporal_multinet.py +20 -12
  19. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/__init__.py +7 -11
  20. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/ast.py +1 -1
  21. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/builder.py +9 -13
  22. py3plex-2.0.8/py3plex/dsl/builder_parser.py +83 -0
  23. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/executor.py +254 -92
  24. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/program/cache.py +44 -17
  25. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/program/executor.py +3 -3
  26. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/program/program.py +144 -104
  27. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/program/types.py +10 -2
  28. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/result.py +65 -5
  29. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/config.py +6 -34
  30. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/graph_ops.py +4 -65
  31. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/api.py +2 -2
  32. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/canonical_format.py +47 -37
  33. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/multiplex.py +31 -8
  34. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/optimizer/rules.py +9 -9
  35. py3plex-2.0.8/py3plex/safe_dsl_expression.py +83 -0
  36. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/temporal_view.py +7 -0
  37. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/null_models.py +3 -3
  38. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/partition.py +12 -13
  39. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/drawing_machinery.py +2 -2
  40. {py3plex-2.0.1 → py3plex-2.0.8/py3plex.egg-info}/PKG-INFO +7 -4
  41. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex.egg-info/SOURCES.txt +21 -0
  42. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex_mcp/__init__.py +2 -2
  43. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex_mcp/server.py +4 -13
  44. {py3plex-2.0.1 → py3plex-2.0.8}/pyproject.toml +5 -2
  45. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_book_conf.py +1 -1
  46. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_book_manuscript_integrity.py +4 -4
  47. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_check_type_coverage.py +137 -7
  48. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_ci_python_versions.py +12 -0
  49. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_cli.py +323 -0
  50. py3plex-2.0.8/tests/test_community_comparison_coverage.py +304 -0
  51. py3plex-2.0.8/tests/test_community_measures_coverage.py +198 -0
  52. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_core_multinet_and_parsers.py +45 -5
  53. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_create_showcase_flow.py +2 -1
  54. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_doc_conf.py +9 -3
  55. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_communities.py +6 -0
  56. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_compiler_pipeline.py +11 -0
  57. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_export.py +49 -0
  58. py3plex-2.0.8/tests/test_dsl_multilayer_measure_topology.py +467 -0
  59. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_v2.py +19 -0
  60. py3plex-2.0.8/tests/test_errors_coverage.py +316 -0
  61. py3plex-2.0.8/tests/test_formal_phase1_alignment.py +140 -0
  62. py3plex-2.0.8/tests/test_io_conversion_formats.py +226 -0
  63. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_link_checker.py +1 -1
  64. py3plex-2.0.8/tests/test_logging_config_unit.py +68 -0
  65. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_mcp_server.py +20 -0
  66. py3plex-2.0.8/tests/test_mdl_benchmark.py +83 -0
  67. py3plex-2.0.8/tests/test_mdl_score.py +767 -0
  68. py3plex-2.0.8/tests/test_mdl_score_corruption_monotonicity.py +115 -0
  69. py3plex-2.0.8/tests/test_mdl_score_reference_differential.py +273 -0
  70. py3plex-2.0.8/tests/test_mdl_score_resolution_limit_sweep.py +158 -0
  71. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_ml_embedding_primitives.py +16 -0
  72. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multilayer_quality_metrics.py +3 -1
  73. py3plex-2.0.8/tests/test_multilayer_quality_metrics_coverage.py +273 -0
  74. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_optimizer_submodules.py +66 -0
  75. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_program.py +83 -9
  76. py3plex-2.0.8/tests/test_program_cache_identity.py +62 -0
  77. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_program_cost_executor.py +7 -7
  78. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_readme_contributor_onboarding.py +28 -0
  79. py3plex-2.0.8/tests/test_safe_expression.py +48 -0
  80. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_temporal_multinet.py +24 -0
  81. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_temporal_view.py +2 -2
  82. py3plex-2.0.8/tests/test_type_coverage_scan.py +10 -0
  83. py3plex-2.0.8/tests/test_utils_search_paths.py +134 -0
  84. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_version_consistency.py +37 -8
  85. py3plex-2.0.1/py3plex/algorithms/community_detection/multilayer_quality_metrics.py +0 -325
  86. py3plex-2.0.1/tests/test_utils_search_paths.py +0 -48
  87. {py3plex-2.0.1 → py3plex-2.0.8}/LICENSE +0 -0
  88. {py3plex-2.0.1 → py3plex-2.0.8}/MANIFEST.in +0 -0
  89. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/__main__.py +0 -0
  90. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/_parallel.py +0 -0
  91. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/agent.py +0 -0
  92. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algebra/__init__.py +0 -0
  93. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algebra/backend.py +0 -0
  94. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algebra/closure.py +0 -0
  95. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algebra/fixed_point.py +0 -0
  96. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algebra/lift.py +0 -0
  97. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algebra/paths.py +0 -0
  98. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algebra/registry.py +0 -0
  99. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algebra/semiring.py +0 -0
  100. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algebra/witness.py +0 -0
  101. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/__init__.py +0 -0
  102. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/advanced_random_generators.py +0 -0
  103. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/attribute_correlation.py +0 -0
  104. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/centrality/__init__.py +0 -0
  105. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/centrality/approx_betweenness.py +0 -0
  106. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/centrality/approx_closeness.py +0 -0
  107. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/centrality/approx_pagerank.py +0 -0
  108. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/centrality/explain.py +0 -0
  109. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/centrality_toolkit.py +0 -0
  110. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_comparison.py +0 -0
  111. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/NoRC.py +0 -0
  112. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/__init__.py +0 -0
  113. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/auto_select.py +0 -0
  114. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/autocommunity.py +0 -0
  115. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/budget.py +0 -0
  116. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/community_measures.py +0 -0
  117. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/community_ranking.py +0 -0
  118. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/community_wrapper.py +0 -0
  119. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/distributional.py +0 -0
  120. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/flow_hierarchy.py +0 -0
  121. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/infomap/__init__.py +0 -0
  122. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/infomap/conftest.py +0 -0
  123. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/infomap/examples/python/example-bipartite.py +0 -0
  124. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/infomap/examples/python/example-file-io.py +0 -0
  125. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/infomap/examples/python/example-multiplex.py +0 -0
  126. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/infomap/examples/python/example-networkx.py +0 -0
  127. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/infomap/examples/python/example-simple.py +0 -0
  128. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/infomap/examples/python/example-trigram-expanded.py +0 -0
  129. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/infomap/examples/python/example-trigram.py +0 -0
  130. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/infomap/infomap.py +0 -0
  131. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/infomap/interfaces/python/setup.py +0 -0
  132. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/leiden_multilayer.py +0 -0
  133. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/leiden_uq.py +0 -0
  134. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/multilayer_benchmark.py +0 -0
  135. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/multilayer_modularity.py +0 -0
  136. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/node_ranking.py +0 -0
  137. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/runner.py +0 -0
  138. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/sbm_metrics.py +0 -0
  139. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/sbm_wrapper.py +0 -0
  140. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/spectral_multilayer.py +0 -0
  141. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/community_detection/successive_halving.py +0 -0
  142. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/curvature/__init__.py +0 -0
  143. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/curvature/ollivier_ricci_multilayer.py +0 -0
  144. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/general/__init__.py +0 -0
  145. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/general/benchmark_classification.py +0 -0
  146. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/general/walkers.py +0 -0
  147. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/graph_summarization.py +0 -0
  148. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/__init__.py +0 -0
  149. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/__main__.py +0 -0
  150. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/assets/builtin.n3 +0 -0
  151. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/core/__init__.py +0 -0
  152. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/core/converters.py +0 -0
  153. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/core/example.py +0 -0
  154. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/core/helpers.py +0 -0
  155. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/core/kb.py +0 -0
  156. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/core/load.py +0 -0
  157. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/core/predicate.py +0 -0
  158. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/core/rule.py +0 -0
  159. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/core/settings.py +0 -0
  160. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/core/term_parsers.py +0 -0
  161. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/learners/__init__.py +0 -0
  162. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/learners/bottomup.py +0 -0
  163. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/learners/learner.py +0 -0
  164. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/learners/optimal.py +0 -0
  165. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/stats/__init__.py +0 -0
  166. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/stats/adjustment.py +0 -0
  167. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/stats/scorefunctions.py +0 -0
  168. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/stats/significance.py +0 -0
  169. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/hedwig/stats/validate.py +0 -0
  170. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/layer_similarity.py +0 -0
  171. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/meta_flow_report.py +0 -0
  172. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/multicentrality.py +0 -0
  173. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/multilayer_algorithms/__init__.py +0 -0
  174. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/multilayer_algorithms/entanglement.py +0 -0
  175. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/multilayer_algorithms/multirank.py +0 -0
  176. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/multilayer_algorithms/multixrank.py +0 -0
  177. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/multilayer_algorithms/supra_matrix_function_centrality.py +0 -0
  178. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/multilayer_algorithms/versatility.py +0 -0
  179. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/multilayer_clustering.py +0 -0
  180. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/network_classification/PPR.py +0 -0
  181. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/network_classification/__init__.py +0 -0
  182. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/network_classification/label_propagation.py +0 -0
  183. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/node_ranking/__init__.py +0 -0
  184. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/node_ranking/node_ranking.py +0 -0
  185. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/requirements_registry.py +0 -0
  186. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/robustness_testing.py +0 -0
  187. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/routing/__init__.py +0 -0
  188. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/routing/multiplex_paths.py +0 -0
  189. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/sbm/__init__.py +0 -0
  190. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/sbm/conversions.py +0 -0
  191. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/sbm/diagnostics.py +0 -0
  192. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/sbm/inference_vi.py +0 -0
  193. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/sbm/model_selection.py +0 -0
  194. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/sbm/multilayer_sbm.py +0 -0
  195. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/sbm/objectives.py +0 -0
  196. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/sbm/uq.py +0 -0
  197. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/sbm/utils.py +0 -0
  198. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/sir_multiplex.py +0 -0
  199. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistical_report.py +0 -0
  200. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistics/__init__.py +0 -0
  201. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistics/basic_statistics.py +0 -0
  202. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistics/bayesian_distances.py +0 -0
  203. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistics/bayesiantests.py +0 -0
  204. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistics/correlation_networks.py +0 -0
  205. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistics/critical_distances.py +0 -0
  206. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistics/enrichment_modules.py +0 -0
  207. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistics/powerlaw.py +0 -0
  208. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistics/stats_comparison.py +0 -0
  209. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/statistics/topology.py +0 -0
  210. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/temporal/__init__.py +0 -0
  211. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/temporal/centrality.py +0 -0
  212. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/temporal/community.py +0 -0
  213. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/temporal_multiplex/__init__.py +0 -0
  214. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/algorithms/term_parsers/__init__.py +0 -0
  215. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/alignment/__init__.py +0 -0
  216. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/alignment/features.py +0 -0
  217. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/alignment/metrics.py +0 -0
  218. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/alignment/solvers.py +0 -0
  219. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/benchmarks/__init__.py +0 -0
  220. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/benchmarks/budget.py +0 -0
  221. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/benchmarks/metrics.py +0 -0
  222. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/benchmarks/runners.py +0 -0
  223. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/centrality/__init__.py +0 -0
  224. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/centrality/robustness.py +0 -0
  225. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/claims/__init__.py +0 -0
  226. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/claims/generator.py +0 -0
  227. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/claims/learner.py +0 -0
  228. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/claims/scorer.py +0 -0
  229. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/claims/types.py +0 -0
  230. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/comparison/__init__.py +0 -0
  231. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/comparison/executor.py +0 -0
  232. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/comparison/metrics.py +0 -0
  233. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/comparison/result.py +0 -0
  234. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/__init__.py +0 -0
  235. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/convert.py +0 -0
  236. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/converters/__init__.py +0 -0
  237. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/converters/dgl_converter.py +0 -0
  238. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/converters/igraph_converter.py +0 -0
  239. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/converters/networkx_converter.py +0 -0
  240. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/converters/pyg_converter.py +0 -0
  241. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/converters/scipy_converter.py +0 -0
  242. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/equality.py +0 -0
  243. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/exceptions.py +0 -0
  244. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/ir.py +0 -0
  245. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/schema.py +0 -0
  246. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/compat/sidecar.py +0 -0
  247. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/contracts/__init__.py +0 -0
  248. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/contracts/contract.py +0 -0
  249. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/contracts/engine.py +0 -0
  250. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/contracts/failure_modes.py +0 -0
  251. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/contracts/predicates.py +0 -0
  252. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/contracts/result.py +0 -0
  253. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/HINMINE/IO.py +0 -0
  254. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/HINMINE/__init__.py +0 -0
  255. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/HINMINE/dataStructures.py +0 -0
  256. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/HINMINE/decomposition.py +0 -0
  257. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/__init__.py +0 -0
  258. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/converters.py +0 -0
  259. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/immutable.py +0 -0
  260. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/lazy_evaluation.py +0 -0
  261. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/nx_compat.py +0 -0
  262. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/schema_validation.py +0 -0
  263. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/supporting.py +0 -0
  264. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/core/types.py +0 -0
  265. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterexamples/__init__.py +0 -0
  266. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterexamples/claim_lang.py +0 -0
  267. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterexamples/ddmin.py +0 -0
  268. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterexamples/engine.py +0 -0
  269. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterexamples/types.py +0 -0
  270. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterexamples/witness.py +0 -0
  271. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterfactual/__init__.py +0 -0
  272. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterfactual/comparator.py +0 -0
  273. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterfactual/engine.py +0 -0
  274. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterfactual/presets.py +0 -0
  275. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterfactual/result.py +0 -0
  276. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/counterfactual/spec.py +0 -0
  277. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/datasets/__init__.py +0 -0
  278. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/datasets/_data/aarhus_cs.edges +0 -0
  279. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/datasets/_data/synthetic_multilayer.edges +0 -0
  280. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/datasets/_generators.py +0 -0
  281. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/datasets/_loaders.py +0 -0
  282. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/diagnostics/__init__.py +0 -0
  283. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/diagnostics/builders.py +0 -0
  284. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/diagnostics/codes.py +0 -0
  285. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/diagnostics/core.py +0 -0
  286. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/diagnostics/utils.py +0 -0
  287. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/algebra.py +0 -0
  288. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/attribution.py +0 -0
  289. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/benchmark.py +0 -0
  290. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/benchmark_result.py +0 -0
  291. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/cache.py +0 -0
  292. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/communities.py +0 -0
  293. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/community_uq.py +0 -0
  294. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/compositional_uq.py +0 -0
  295. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/context.py +0 -0
  296. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/errors.py +0 -0
  297. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/executor_semiring.py +0 -0
  298. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/executors/__init__.py +0 -0
  299. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/executors/benchmark_executor.py +0 -0
  300. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/explain.py +0 -0
  301. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/export.py +0 -0
  302. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/expressions.py +0 -0
  303. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/fastpath.py +0 -0
  304. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/layers.py +0 -0
  305. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/__init__.py +0 -0
  306. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/diagnostic.py +0 -0
  307. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/lint_context.py +0 -0
  308. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/rules/__init__.py +0 -0
  309. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/rules/base.py +0 -0
  310. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/rules/dsl001_unknown_layer.py +0 -0
  311. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/rules/dsl002_unknown_attribute.py +0 -0
  312. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/rules/dsl101_type_mismatch.py +0 -0
  313. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/rules/dsl201_unsatisfiable.py +0 -0
  314. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/rules/dsl202_redundant.py +0 -0
  315. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/rules/perf301_full_scan.py +0 -0
  316. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/rules/perf302_cross_layer.py +0 -0
  317. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/schema.py +0 -0
  318. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/type_resolver.py +0 -0
  319. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/lint/types.py +0 -0
  320. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/metrics.py +0 -0
  321. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/operator_registry.py +0 -0
  322. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/operators.py +0 -0
  323. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/patterns/__init__.py +0 -0
  324. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/patterns/builder.py +0 -0
  325. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/patterns/compiler.py +0 -0
  326. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/patterns/engine.py +0 -0
  327. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/patterns/ir.py +0 -0
  328. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/patterns/result.py +0 -0
  329. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/plan.py +0 -0
  330. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/planner.py +0 -0
  331. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/predictive.py +0 -0
  332. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/program/__init__.py +0 -0
  333. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/program/cost.py +0 -0
  334. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/program/diff.py +0 -0
  335. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/program/distribution.py +0 -0
  336. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/program/explain.py +0 -0
  337. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/program/rewrite.py +0 -0
  338. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/provenance.py +0 -0
  339. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/reduction.py +0 -0
  340. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/registry.py +0 -0
  341. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/selection_uq.py +0 -0
  342. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/serializer.py +0 -0
  343. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/uq_algebra.py +0 -0
  344. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/uq_resolution.py +0 -0
  345. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl/warnings.py +0 -0
  346. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dsl_legacy.py +0 -0
  347. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/__init__.py +0 -0
  348. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/_utils.py +0 -0
  349. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/ast.py +0 -0
  350. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/builder.py +0 -0
  351. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/compartmental.py +0 -0
  352. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/core.py +0 -0
  353. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/errors.py +0 -0
  354. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/executor.py +0 -0
  355. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/models.py +0 -0
  356. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/processes.py +0 -0
  357. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/registry.py +0 -0
  358. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/result.py +0 -0
  359. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/dynamics/serializer.py +0 -0
  360. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/embeddings/__init__.py +0 -0
  361. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/embeddings/base.py +0 -0
  362. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/embeddings/cache.py +0 -0
  363. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/embeddings/link_ops.py +0 -0
  364. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/embeddings/metapath2vec.py +0 -0
  365. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/embeddings/netmf.py +0 -0
  366. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ergonomics.py +0 -0
  367. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/errors.py +0 -0
  368. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/exceptions.py +0 -0
  369. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/experiments/__init__.py +0 -0
  370. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/experiments/artifacts.py +0 -0
  371. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/experiments/cli.py +0 -0
  372. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/experiments/env.py +0 -0
  373. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/experiments/errors.py +0 -0
  374. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/experiments/model.py +0 -0
  375. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/experiments/runner.py +0 -0
  376. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/experiments/store.py +0 -0
  377. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/experiments/utils.py +0 -0
  378. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/fast_examples.py +0 -0
  379. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/__init__.py +0 -0
  380. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/converters.py +0 -0
  381. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/exceptions.py +0 -0
  382. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/formats/__init__.py +0 -0
  383. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/formats/arrow_format.py +0 -0
  384. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/formats/csv_format.py +0 -0
  385. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/formats/json_format.py +0 -0
  386. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/multinet_bridge.py +0 -0
  387. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/parquet_format.py +0 -0
  388. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/io/schema.py +0 -0
  389. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/lab/__init__.py +0 -0
  390. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/lab/base.py +0 -0
  391. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/linter.py +0 -0
  392. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/logging_config.py +0 -0
  393. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/meta/__init__.py +0 -0
  394. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/meta/builder.py +0 -0
  395. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/meta/result.py +0 -0
  396. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/meta/stats.py +0 -0
  397. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/meta/utils.py +0 -0
  398. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/__init__.py +0 -0
  399. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/__init__.py +0 -0
  400. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/base.py +0 -0
  401. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/deepwalk.py +0 -0
  402. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/evaluation.py +0 -0
  403. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/line.py +0 -0
  404. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/metapath2vec.py +0 -0
  405. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/netmf.py +0 -0
  406. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/node2vec.py +0 -0
  407. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/similarity.py +0 -0
  408. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/trainer.py +0 -0
  409. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/ml/embedding/utils.py +0 -0
  410. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/multinet/__init__.py +0 -0
  411. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/multinet/aggregation.py +0 -0
  412. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/nullmodels/__init__.py +0 -0
  413. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/nullmodels/executor.py +0 -0
  414. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/nullmodels/models.py +0 -0
  415. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/nullmodels/result.py +0 -0
  416. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/optimizer/__init__.py +0 -0
  417. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/optimizer/cost_model.py +0 -0
  418. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/optimizer/logical_plan.py +0 -0
  419. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/optimizer/optimizer.py +0 -0
  420. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/optimizer/physical_plan.py +0 -0
  421. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/optimizer/plan_nodes.py +0 -0
  422. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/out_of_core/__init__.py +0 -0
  423. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/out_of_core/cli.py +0 -0
  424. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/out_of_core/errors.py +0 -0
  425. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/out_of_core/executor.py +0 -0
  426. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/out_of_core/network.py +0 -0
  427. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/out_of_core/operators.py +0 -0
  428. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/out_of_core/readers.py +0 -0
  429. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/out_of_core/schema.py +0 -0
  430. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/out_of_core/spill.py +0 -0
  431. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/out_of_core/utils.py +0 -0
  432. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/paths/__init__.py +0 -0
  433. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/paths/algorithms.py +0 -0
  434. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/paths/executor.py +0 -0
  435. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/paths/result.py +0 -0
  436. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/pipeline.py +0 -0
  437. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/plugins/__init__.py +0 -0
  438. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/plugins/base.py +0 -0
  439. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/plugins/examples.py +0 -0
  440. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/plugins/registry.py +0 -0
  441. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/profiling.py +0 -0
  442. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/provenance/__init__.py +0 -0
  443. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/provenance/bundle.py +0 -0
  444. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/provenance/capture.py +0 -0
  445. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/provenance/replay.py +0 -0
  446. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/provenance/schema.py +0 -0
  447. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/requirements.py +0 -0
  448. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/robustness/__init__.py +0 -0
  449. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/robustness/experiments.py +0 -0
  450. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/robustness/perturbations.py +0 -0
  451. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/runtime/__init__.py +0 -0
  452. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/runtime/capabilities.py +0 -0
  453. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/selection/__init__.py +0 -0
  454. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/selection/capabilities.py +0 -0
  455. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/selection/community_registry.py +0 -0
  456. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/selection/evaluate.py +0 -0
  457. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/selection/metric_registry.py +0 -0
  458. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/selection/result.py +0 -0
  459. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/selection/wins.py +0 -0
  460. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/semiring/__init__.py +0 -0
  461. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/semiring/core.py +0 -0
  462. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/semiring/engine.py +0 -0
  463. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/semiring/pareto.py +0 -0
  464. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/semiring/registry.py +0 -0
  465. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/semiring/types.py +0 -0
  466. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/sensitivity/__init__.py +0 -0
  467. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/sensitivity/executor.py +0 -0
  468. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/sensitivity/metrics.py +0 -0
  469. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/sensitivity/perturbations.py +0 -0
  470. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/sensitivity/types.py +0 -0
  471. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/stats/__init__.py +0 -0
  472. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/stats/provenance.py +0 -0
  473. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/stats/registry.py +0 -0
  474. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/stats/statvalue.py +0 -0
  475. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/stats/uncertainty.py +0 -0
  476. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/temporal_utils.py +0 -0
  477. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/temporal_utils_extended.py +0 -0
  478. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/__init__.py +0 -0
  479. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/bootstrap.py +0 -0
  480. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/ci_utils.py +0 -0
  481. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/community_ensemble.py +0 -0
  482. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/community_result.py +0 -0
  483. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/context.py +0 -0
  484. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/estimation.py +0 -0
  485. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/noise_models.py +0 -0
  486. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/partition_metrics.py +0 -0
  487. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/partition_reducers.py +0 -0
  488. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/partition_types.py +0 -0
  489. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/partition_uq.py +0 -0
  490. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/plan.py +0 -0
  491. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/reducers/__init__.py +0 -0
  492. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/reducers/base.py +0 -0
  493. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/resampling_graph.py +0 -0
  494. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/runner.py +0 -0
  495. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/selection_execution.py +0 -0
  496. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/selection_reducers.py +0 -0
  497. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/selection_types.py +0 -0
  498. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/selection_uq.py +0 -0
  499. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/stratification.py +0 -0
  500. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/uncertainty/types.py +0 -0
  501. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/utils.py +0 -0
  502. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/validation.py +0 -0
  503. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/__init__.py +0 -0
  504. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/benchmark_visualizations.py +0 -0
  505. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/bezier.py +0 -0
  506. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/colors.py +0 -0
  507. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/embedding_visualization/__init__.py +0 -0
  508. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/embedding_visualization/embedding_tools.py +0 -0
  509. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/embedding_visualization/embedding_visualization.py +0 -0
  510. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/fa2/__init__.py +0 -0
  511. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/fa2/fa2util.py +0 -0
  512. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/fa2/forceatlas2.py +0 -0
  513. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/layout_algorithms.py +0 -0
  514. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/multilayer.py +0 -0
  515. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/polyfit.py +0 -0
  516. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/pymnet_style.py +0 -0
  517. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/ricci_layout.py +0 -0
  518. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/ricci_multilayer_vis.py +0 -0
  519. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/visualization/sankey.py +0 -0
  520. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/workflows.py +0 -0
  521. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/wrappers/__init__.py +0 -0
  522. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/wrappers/benchmark_nodes.py +0 -0
  523. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/wrappers/r_interop.py +0 -0
  524. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex/wrappers/train_node2vec_embedding.py +0 -0
  525. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex.egg-info/dependency_links.txt +0 -0
  526. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex.egg-info/entry_points.txt +0 -0
  527. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex.egg-info/not-zip-safe +0 -0
  528. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex.egg-info/requires.txt +0 -0
  529. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex.egg-info/top_level.txt +0 -0
  530. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex_mcp/errors.py +0 -0
  531. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex_mcp/registry.py +0 -0
  532. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex_mcp/safe_paths.py +0 -0
  533. {py3plex-2.0.1 → py3plex-2.0.8}/py3plex_mcp/schemas.py +0 -0
  534. {py3plex-2.0.1 → py3plex-2.0.8}/setup.cfg +0 -0
  535. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_advanced_metrics_properties.py +0 -0
  536. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_agent_api.py +0 -0
  537. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_agents_documentation_claims.py +0 -0
  538. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_agents_ergonomics_features.py +0 -0
  539. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_agents_golden_paths.py +0 -0
  540. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_aggregation.py +0 -0
  541. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algebra_backend.py +0 -0
  542. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algebra_core.py +0 -0
  543. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algebra_fixed_point.py +0 -0
  544. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algebra_paths.py +0 -0
  545. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algebra_registry.py +0 -0
  546. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algebra_witness.py +0 -0
  547. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algorithm_properties.py +0 -0
  548. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algorithms_attribute_correlation.py +0 -0
  549. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algorithms_correlation_networks.py +0 -0
  550. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algorithms_init.py +0 -0
  551. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algorithms_random_generators.py +0 -0
  552. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algorithms_requirements_registry.py +0 -0
  553. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_algorithms_statistics_bayesian_distances.py +0 -0
  554. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_alignment.py +0 -0
  555. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_alignment_contracts.py +0 -0
  556. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_alignment_correctness_additional.py +0 -0
  557. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_approximate_centrality.py +0 -0
  558. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_ast_roundtrip.py +0 -0
  559. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_ast_roundtrip_integration.py +0 -0
  560. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_attribute_correlation.py +0 -0
  561. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_attribute_correlation_contracts.py +0 -0
  562. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_auto_community.py +0 -0
  563. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_autocommunity_benchmarks.py +0 -0
  564. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_autocommunity_executor.py +0 -0
  565. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_autocommunity_meta.py +0 -0
  566. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_autocommunity_successive_halving.py +0 -0
  567. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_bayesian_distances.py +0 -0
  568. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_bench_aggregation_unit.py +0 -0
  569. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_benchmark_budget_fairness.py +0 -0
  570. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_benchmark_dsl_basic.py +0 -0
  571. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_benchmark_integration.py +0 -0
  572. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_benchmark_multiplex_centrality.py +0 -0
  573. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_benchmark_time.py +0 -0
  574. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_benchmarks_budget.py +0 -0
  575. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_benchmarks_init.py +0 -0
  576. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_book_snippets.py +0 -0
  577. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_builder_dsl_mutate.py +0 -0
  578. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_capabilities_basic.py +0 -0
  579. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_capabilities_optional_missing.py +0 -0
  580. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_centrality_explain.py +0 -0
  581. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_centrality_explain_integration.py +0 -0
  582. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_centrality_robustness.py +0 -0
  583. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_centrality_robustness_oracles.py +0 -0
  584. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_centrality_uncertainty.py +0 -0
  585. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_centrality_weight_handling.py +0 -0
  586. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_check_api_consistency.py +0 -0
  587. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_check_doc_coverage.py +0 -0
  588. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_claim_learning.py +0 -0
  589. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_claims_types.py +0 -0
  590. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_cli_check.py +0 -0
  591. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_cli_ergonomics.py +0 -0
  592. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_cli_piping.py +0 -0
  593. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_clustering_multilayer.py +0 -0
  594. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_code_improvements.py +0 -0
  595. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_community_detection_modules.py +0 -0
  596. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_community_distribution.py +0 -0
  597. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_community_measures.py +0 -0
  598. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_comparison.py +0 -0
  599. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_comparison_executor.py +0 -0
  600. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_comparison_metrics.py +0 -0
  601. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_comparison_metrics_additional.py +0 -0
  602. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_comparison_result.py +0 -0
  603. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_comparison_uninitialized_and_resistance_oracles.py +0 -0
  604. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_compat_exceptions.py +0 -0
  605. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_compat_roundtrip.py +0 -0
  606. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_config_api.py +0 -0
  607. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_config_benchmark.py +0 -0
  608. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_contracts.py +0 -0
  609. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_contracts_basic.py +0 -0
  610. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_contracts_extended.py +0 -0
  611. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_contracts_failure_modes.py +0 -0
  612. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_contracts_integration.py +0 -0
  613. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_core_functionality.py +0 -0
  614. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_core_immutable.py +0 -0
  615. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_core_lazy_evaluation.py +0 -0
  616. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_core_multinet_correctness.py +0 -0
  617. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_core_multiplex_edges.py +0 -0
  618. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_core_schema_validation.py +0 -0
  619. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_core_supporting.py +0 -0
  620. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_correlation_networks.py +0 -0
  621. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_counterexamples.py +0 -0
  622. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_counterexamples_properties.py +0 -0
  623. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_counterfactual.py +0 -0
  624. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_counterfactual_presets.py +0 -0
  625. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_coverage_grouping.py +0 -0
  626. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_create_mosaic_banner.py +0 -0
  627. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_crosshair_pure_functions.py +0 -0
  628. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_data_files_presence.py +0 -0
  629. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_datasets.py +0 -0
  630. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_datasets_contracts.py +0 -0
  631. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_datasets_oracles.py +0 -0
  632. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_degenerate_networks.py +0 -0
  633. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dependency_cleanup.py +0 -0
  634. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_determinism_randomness.py +0 -0
  635. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_diagnostics.py +0 -0
  636. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_diagnostics_utils.py +0 -0
  637. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_docs_embeddings_section.py +0 -0
  638. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_docs_examples.py +0 -0
  639. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_docs_quality_pass.py +0 -0
  640. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_doctests.py +0 -0
  641. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dplyr_integration.py +0 -0
  642. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl.py +0 -0
  643. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_aggregation_enhancements.py +0 -0
  644. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_ast_equivalence.py +0 -0
  645. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_ast_immutability.py +0 -0
  646. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_auto_community.py +0 -0
  647. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_community_filtering.py +0 -0
  648. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_community_uq_integration.py +0 -0
  649. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_compact_compute.py +0 -0
  650. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_compiler_explain.py +0 -0
  651. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_compositional_uq.py +0 -0
  652. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_condition_semantics.py +0 -0
  653. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_d_factory.py +0 -0
  654. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_documentation_examples.py +0 -0
  655. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_dplyr_style.py +0 -0
  656. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_dynamics_integration.py +0 -0
  657. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_edge_grouping_coverage.py +0 -0
  658. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_edge_queries.py +0 -0
  659. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_enhancements.py +0 -0
  660. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_ergonomics.py +0 -0
  661. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_errors.py +0 -0
  662. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_errors_extended.py +0 -0
  663. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_executor_additional.py +0 -0
  664. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_explain.py +0 -0
  665. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_expressions.py +0 -0
  666. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_extensions.py +0 -0
  667. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_graphops_equivalence.py +0 -0
  668. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_grouping_coverage.py +0 -0
  669. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_interactive.py +0 -0
  670. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_joins.py +0 -0
  671. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_layer_resolution.py +0 -0
  672. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_layer_selection.py +0 -0
  673. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_layer_set_algebra.py +0 -0
  674. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_legacy_approximate.py +0 -0
  675. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_legacy_edges.py +0 -0
  676. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_lint.py +0 -0
  677. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_metric_registry.py +0 -0
  678. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_operators.py +0 -0
  679. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_patterns.py +0 -0
  680. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_patterns_correctness.py +0 -0
  681. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_patterns_quick_reference.py +0 -0
  682. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_pipes.py +0 -0
  683. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_planner.py +0 -0
  684. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_planner_config.py +0 -0
  685. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_predict_reduce.py +0 -0
  686. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_program_rewrite.py +0 -0
  687. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_program_types.py +0 -0
  688. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_progress_logging.py +0 -0
  689. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_properties.py +0 -0
  690. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_provenance.py +0 -0
  691. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_query_optimization.py +0 -0
  692. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_query_zoo.py +0 -0
  693. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_result_algebra_edge_cases.py +0 -0
  694. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_selection_fastpath.py +0 -0
  695. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_semiring_integration.py +0 -0
  696. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_serializer.py +0 -0
  697. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_smart_defaults.py +0 -0
  698. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_temporal_range_execution.py +0 -0
  699. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_uncertainty.py +0 -0
  700. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_uq_ergonomics.py +0 -0
  701. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_uq_propagation.py +0 -0
  702. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dsl_zoo_features.py +0 -0
  703. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dynamics.py +0 -0
  704. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dynamics_algorithm_contracts.py +0 -0
  705. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dynamics_config_and_results_correctness.py +0 -0
  706. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dynamics_conservation.py +0 -0
  707. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dynamics_core.py +0 -0
  708. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dynamics_executor_edge_cases.py +0 -0
  709. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dynamics_metamorphic.py +0 -0
  710. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dynamics_parallel_determinism.py +0 -0
  711. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dynamics_reference_runs.py +0 -0
  712. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dynamics_uq_integration.py +0 -0
  713. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_dynamics_utils.py +0 -0
  714. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_edge_cases.py +0 -0
  715. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_edgelist_format.py +0 -0
  716. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_embeddings_direct_units.py +0 -0
  717. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_ergonomic_helpers.py +0 -0
  718. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_ergonomics.py +0 -0
  719. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_ergonomics_helpers.py +0 -0
  720. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_errors.py +0 -0
  721. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_CBSSD.py +0 -0
  722. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_community_detection.py +0 -0
  723. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_decomposition_and_classification.py +0 -0
  724. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_decomposition_ground_truth.py +0 -0
  725. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_dsl_builder_api.py +0 -0
  726. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_dynamics_core_examples.py +0 -0
  727. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_embedding_construction.py +0 -0
  728. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_embedding_visualization.py +0 -0
  729. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_incidence_gadget_encoding.py +0 -0
  730. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_interactive_multilayer.py +0 -0
  731. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_inverse_network.py +0 -0
  732. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_layer_extraction.py +0 -0
  733. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_manipulation.py +0 -0
  734. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_multilayer_vectorized_aggregation.py +0 -0
  735. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_multiplex_aggregate.py +0 -0
  736. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_multiplex_dynamics.py +0 -0
  737. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_n2v_embedding.py +0 -0
  738. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_network_decomposition.py +0 -0
  739. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_network_decomposition_meta_paths.py +0 -0
  740. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_numeric_encoding.py +0 -0
  741. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_pattern_matching.py +0 -0
  742. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_example_ppr.py +0 -0
  743. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_examples_zoo_consolidation.py +0 -0
  744. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_exception_taxonomy.py +0 -0
  745. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_exceptions.py +0 -0
  746. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_experiments.py +0 -0
  747. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_explain_attribution.py +0 -0
  748. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_fast_examples.py +0 -0
  749. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_flagship_progress_demo.py +0 -0
  750. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_flow_hierarchy.py +0 -0
  751. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_fuzzing_properties.py +0 -0
  752. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_generate_all_outputs.py +0 -0
  753. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_generate_quickstart_outputs.py +0 -0
  754. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_generate_visualization_images.py +0 -0
  755. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_golden_toy_examples.py +0 -0
  756. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_graph_ops.py +0 -0
  757. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_graph_summarization.py +0 -0
  758. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_hedwig_adjustment.py +0 -0
  759. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_hedwig_significance.py +0 -0
  760. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_improved_errors.py +0 -0
  761. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_incidence_gadget_encoding.py +0 -0
  762. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_infomap_fix.py +0 -0
  763. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_interlayer_links_fix.py +0 -0
  764. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_io_api_edge_cases.py +0 -0
  765. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_io_arrow.py +0 -0
  766. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_io_contracts_additional.py +0 -0
  767. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_io_converters.py +0 -0
  768. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_io_exceptions.py +0 -0
  769. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_io_integration.py +0 -0
  770. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_io_roundtrip.py +0 -0
  771. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_io_schema.py +0 -0
  772. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_issue_19_fix.py +0 -0
  773. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_lab.py +0 -0
  774. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_lab_additional.py +0 -0
  775. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_lab_correctness.py +0 -0
  776. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_label_propagation.py +0 -0
  777. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_layer_extraction_fix.py +0 -0
  778. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_layer_similarity.py +0 -0
  779. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_layout_algorithms.py +0 -0
  780. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_lazy_evaluation.py +0 -0
  781. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_leiden_multilayer.py +0 -0
  782. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_linter.py +0 -0
  783. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_logging_conversion.py +0 -0
  784. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_main_module.py +0 -0
  785. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_master_regulators_example.py +0 -0
  786. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_math_invariants.py +0 -0
  787. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_meta_analysis.py +0 -0
  788. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_meta_flow_report.py +0 -0
  789. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_meta_utils.py +0 -0
  790. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_metamorphic.py +0 -0
  791. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_metapath2vec.py +0 -0
  792. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_ml_embedding_evaluation.py +0 -0
  793. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_monoplex_nx_wrapper.py +0 -0
  794. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_mpc.py +0 -0
  795. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multilayer_centrality.py +0 -0
  796. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multilayer_clustering_coefficients.py +0 -0
  797. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multilayer_cornercases.py +0 -0
  798. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multilayer_edge_fix.py +0 -0
  799. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multilayer_embedding_models.py +0 -0
  800. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multilayer_integration.py +0 -0
  801. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multilayer_leiden_uq.py +0 -0
  802. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multilayer_modularity.py +0 -0
  803. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multilayer_statistics.py +0 -0
  804. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multilayer_visualizations.py +0 -0
  805. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multinet_aggregation.py +0 -0
  806. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multinet_aggregation_additional.py +0 -0
  807. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multiplex_layer_interop.py +0 -0
  808. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multiplex_participation.py +0 -0
  809. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multiplex_properties.py +0 -0
  810. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multirank.py +0 -0
  811. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_multixrank.py +0 -0
  812. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_network_conversion.py +0 -0
  813. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_network_version.py +0 -0
  814. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_networkx_compatibility.py +0 -0
  815. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_new_algorithms.py +0 -0
  816. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_new_multilayer_metrics.py +0 -0
  817. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_node_edge_parity.py +0 -0
  818. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_node_ranking_comprehensive.py +0 -0
  819. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_norc.py +0 -0
  820. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_nullmodel_sanity.py +0 -0
  821. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_nullmodels.py +0 -0
  822. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_nullmodels_contracts.py +0 -0
  823. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_nx_compat_extended.py +0 -0
  824. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_ollivier_ricci_multilayer.py +0 -0
  825. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_out_of_core.py +0 -0
  826. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_parallel.py +0 -0
  827. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_parallel_execution.py +0 -0
  828. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_parsers_comprehensive.py +0 -0
  829. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_parsers_coverage.py +0 -0
  830. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_partition_uq.py +0 -0
  831. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_partition_uq_integration.py +0 -0
  832. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_paths.py +0 -0
  833. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_paths_additional.py +0 -0
  834. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_paths_contracts.py +0 -0
  835. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_paths_executor.py +0 -0
  836. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_paths_result.py +0 -0
  837. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_performance_core.py +0 -0
  838. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_pipeline.py +0 -0
  839. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_plugin_examples.py +0 -0
  840. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_plugin_system.py +0 -0
  841. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_plugins.py +0 -0
  842. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_plugins_contracts.py +0 -0
  843. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_profiling.py +0 -0
  844. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_profiling_additional.py +0 -0
  845. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_properties.py +0 -0
  846. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_provenance_canonical.py +0 -0
  847. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_provenance_replay.py +0 -0
  848. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_provenance_schema.py +0 -0
  849. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_public_api_exports.py +0 -0
  850. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_pymnet_style.py +0 -0
  851. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_pypi_publish_workflow.py +0 -0
  852. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_query_algebra.py +0 -0
  853. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_query_equivalence.py +0 -0
  854. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_r_interop.py +0 -0
  855. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_random_generators_additional.py +0 -0
  856. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_random_generators_extended.py +0 -0
  857. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_random_walkers.py +0 -0
  858. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_random_walks.py +0 -0
  859. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_readme_flagship_example.py +0 -0
  860. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_requirements.py +0 -0
  861. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_result_explain_debug.py +0 -0
  862. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_ricci_visualization.py +0 -0
  863. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_robustness.py +0 -0
  864. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_robustness_additional.py +0 -0
  865. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_robustness_testing.py +0 -0
  866. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_root_conftest.py +0 -0
  867. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_roundtrip_invariants.py +0 -0
  868. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_run_quickstart_snippets.py +0 -0
  869. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_sankey_visualization.py +0 -0
  870. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_sbm_autocommunity.py +0 -0
  871. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_sbm_generator.py +0 -0
  872. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_sbm_metrics.py +0 -0
  873. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_sbm_runner_integration.py +0 -0
  874. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_schema_and_immutable.py +0 -0
  875. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_seeding.py +0 -0
  876. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_selection_uq.py +0 -0
  877. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_selection_uq_empty_groups.py +0 -0
  878. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_selection_uq_integration.py +0 -0
  879. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_semiring_negative_cases.py +0 -0
  880. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_semiring_pareto.py +0 -0
  881. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_semiring_registry.py +0 -0
  882. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_semiring_types.py +0 -0
  883. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_semiring_verification.py +0 -0
  884. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_sensitivity_executor.py +0 -0
  885. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_sidecar.py +0 -0
  886. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_sir_epidemic.py +0 -0
  887. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_sir_long_convergence.py +0 -0
  888. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_sir_multiplex.py +0 -0
  889. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_spectral_multilayer.py +0 -0
  890. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_statistical_report.py +0 -0
  891. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_stats_comparison.py +0 -0
  892. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_stats_core.py +0 -0
  893. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_stats_edge_cases.py +0 -0
  894. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_stats_provenance.py +0 -0
  895. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_stats_provenance_dataclass.py +0 -0
  896. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_stats_registry.py +0 -0
  897. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_stats_scalar_uncertainty.py +0 -0
  898. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_stats_verify.py +0 -0
  899. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_stratified_uq.py +0 -0
  900. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_streaming_topk.py +0 -0
  901. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_successive_halving.py +0 -0
  902. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_supporting_extended.py +0 -0
  903. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_supra_matrix_function_centrality.py +0 -0
  904. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_temporal.py +0 -0
  905. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_temporal_algorithms.py +0 -0
  906. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_temporal_builder.py +0 -0
  907. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_temporal_dsl.py +0 -0
  908. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_temporal_duration_parsing.py +0 -0
  909. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_temporal_utils.py +0 -0
  910. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_temporal_utils_extended.py +0 -0
  911. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_temporal_windowed_queries.py +0 -0
  912. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_tensor_representation.py +0 -0
  913. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_tutorial_10min.py +0 -0
  914. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uncertainty.py +0 -0
  915. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uncertainty_additional.py +0 -0
  916. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uncertainty_builder_integration.py +0 -0
  917. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uncertainty_defaults.py +0 -0
  918. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uncertainty_dsl_integration.py +0 -0
  919. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uncertainty_engines.py +0 -0
  920. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uncertainty_oracles.py +0 -0
  921. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uncertainty_runner.py +0 -0
  922. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uq_algebra.py +0 -0
  923. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uq_integration.py +0 -0
  924. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uq_resolution.py +0 -0
  925. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_uq_spine.py +0 -0
  926. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_user_journey_simulation.py +0 -0
  927. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_utils.py +0 -0
  928. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_utils_coverage.py +0 -0
  929. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_utils_extended.py +0 -0
  930. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_validation.py +0 -0
  931. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_validation_module.py +0 -0
  932. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_verification_api_differential.py +0 -0
  933. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_verification_centrality.py +0 -0
  934. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_verification_communities.py +0 -0
  935. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_verification_determinism_parallelism.py +0 -0
  936. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_verification_dsl_equivalence.py +0 -0
  937. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_verification_metamorphic_harness.py +0 -0
  938. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_verification_provenance_oracles.py +0 -0
  939. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_versatility.py +0 -0
  940. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_visualization_benchmark.py +0 -0
  941. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_visualization_bezier.py +0 -0
  942. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_visualization_colors.py +0 -0
  943. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_visualization_imports.py +0 -0
  944. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_visualization_layouts.py +0 -0
  945. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_visualization_multilayer_additional.py +0 -0
  946. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_visualization_polyfit.py +0 -0
  947. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_visualization_ricci_layout_helpers.py +0 -0
  948. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_visualization_supra_heatmap.py +0 -0
  949. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_visualize_matrix_fix.py +0 -0
  950. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_workflows.py +0 -0
  951. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_wrappers_additional.py +0 -0
  952. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_wrappers_benchmark_nodes.py +0 -0
  953. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_wrappers_node2vec.py +0 -0
  954. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_wrappers_r_interop.py +0 -0
  955. {py3plex-2.0.1 → py3plex-2.0.8}/tests/test_wrappers_train_node2vec.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: py3plex
3
- Version: 2.0.1
3
+ Version: 2.0.8
4
4
  Summary: A Multilayer network analysis python3 library
5
5
  Author-email: Blaž Škrlj <blaz.skrlj@ijs.si>
6
6
  License: MIT
@@ -106,19 +106,22 @@ Dynamic: license-file
106
106
  <img src="https://github.com/user-attachments/assets/47e16a25-cd58-41eb-9ccd-b40191758d91" alt="py3plex logo" width="400">
107
107
 
108
108
  [![Tests](https://github.com/SkBlaz/py3plex/actions/workflows/tests.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/tests.yml)
109
+ [![Test coverage](https://img.shields.io/badge/test_coverage-40.1%25-green)](https://github.com/SkBlaz/py3plex/actions/workflows/tests.yml)
110
+ [![Type Coverage](https://img.shields.io/badge/type_coverage-79.1%25-yellowgreen)](https://github.com/SkBlaz/py3plex/actions/workflows/type-coverage.yml)
109
111
  [![Examples](https://github.com/SkBlaz/py3plex/actions/workflows/examples.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/examples.yml)
110
112
  [![Tutorial](https://github.com/SkBlaz/py3plex/actions/workflows/tutorial-validation.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/tutorial-validation.yml)
111
113
  [![Code Quality](https://github.com/SkBlaz/py3plex/actions/workflows/code-quality.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/code-quality.yml)
112
114
  [![Benchmarks](https://github.com/SkBlaz/py3plex/actions/workflows/benchmarks.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/benchmarks.yml)
113
115
  [![Documentation](https://github.com/SkBlaz/py3plex/actions/workflows/doc-coverage.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/doc-coverage.yml)
114
116
  [![Formal Verification](https://github.com/SkBlaz/py3plex/actions/workflows/verify.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/verify.yml)
117
+ [![Lean formal verification](https://github.com/SkBlaz/py3plex/actions/workflows/formal.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/formal.yml)
115
118
  [![Fuzzing](https://github.com/SkBlaz/py3plex/actions/workflows/fuzzing.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/fuzzing.yml)
116
- [![PyPI version](https://img.shields.io/pypi/v/py3plex.svg)](https://pypi.org/project/py3plex/)
119
+ [![PyPI version](https://img.shields.io/pypi/v/py3plex.svg?cacheSeconds=300)](https://pypi.org/project/py3plex/)
117
120
  [![PyPI - Downloads](https://img.shields.io/pypi/dm/py3plex)](https://pypistats.org/packages/py3plex)
118
121
  ![CLI Tool](https://img.shields.io/badge/CLI%20Tool-Available-brightgreen)
119
122
  ![Docker](https://img.shields.io/badge/Docker-Available-blue)
120
- ![Lines of Code](https://img.shields.io/badge/lines-211.9K-blue)
121
- ![Test Count](https://img.shields.io/badge/tests-9.3K-blue)
123
+ ![Lines of Code](https://img.shields.io/badge/lines-213.8K-blue)
124
+ ![Test Count](https://img.shields.io/badge/tests-9.7K-blue)
122
125
 
123
126
  *Multilayer networks* are complex networks with additional information assigned to nodes or edges (or both). This library includes
124
127
  some of the state-of-the-art algorithms for decomposition, visualization and analysis of such networks.
@@ -2,19 +2,22 @@
2
2
  <img src="https://github.com/user-attachments/assets/47e16a25-cd58-41eb-9ccd-b40191758d91" alt="py3plex logo" width="400">
3
3
 
4
4
  [![Tests](https://github.com/SkBlaz/py3plex/actions/workflows/tests.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/tests.yml)
5
+ [![Test coverage](https://img.shields.io/badge/test_coverage-40.1%25-green)](https://github.com/SkBlaz/py3plex/actions/workflows/tests.yml)
6
+ [![Type Coverage](https://img.shields.io/badge/type_coverage-79.1%25-yellowgreen)](https://github.com/SkBlaz/py3plex/actions/workflows/type-coverage.yml)
5
7
  [![Examples](https://github.com/SkBlaz/py3plex/actions/workflows/examples.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/examples.yml)
6
8
  [![Tutorial](https://github.com/SkBlaz/py3plex/actions/workflows/tutorial-validation.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/tutorial-validation.yml)
7
9
  [![Code Quality](https://github.com/SkBlaz/py3plex/actions/workflows/code-quality.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/code-quality.yml)
8
10
  [![Benchmarks](https://github.com/SkBlaz/py3plex/actions/workflows/benchmarks.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/benchmarks.yml)
9
11
  [![Documentation](https://github.com/SkBlaz/py3plex/actions/workflows/doc-coverage.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/doc-coverage.yml)
10
12
  [![Formal Verification](https://github.com/SkBlaz/py3plex/actions/workflows/verify.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/verify.yml)
13
+ [![Lean formal verification](https://github.com/SkBlaz/py3plex/actions/workflows/formal.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/formal.yml)
11
14
  [![Fuzzing](https://github.com/SkBlaz/py3plex/actions/workflows/fuzzing.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/fuzzing.yml)
12
- [![PyPI version](https://img.shields.io/pypi/v/py3plex.svg)](https://pypi.org/project/py3plex/)
15
+ [![PyPI version](https://img.shields.io/pypi/v/py3plex.svg?cacheSeconds=300)](https://pypi.org/project/py3plex/)
13
16
  [![PyPI - Downloads](https://img.shields.io/pypi/dm/py3plex)](https://pypistats.org/packages/py3plex)
14
17
  ![CLI Tool](https://img.shields.io/badge/CLI%20Tool-Available-brightgreen)
15
18
  ![Docker](https://img.shields.io/badge/Docker-Available-blue)
16
- ![Lines of Code](https://img.shields.io/badge/lines-211.9K-blue)
17
- ![Test Count](https://img.shields.io/badge/tests-9.3K-blue)
19
+ ![Lines of Code](https://img.shields.io/badge/lines-213.8K-blue)
20
+ ![Test Count](https://img.shields.io/badge/tests-9.7K-blue)
18
21
 
19
22
  *Multilayer networks* are complex networks with additional information assigned to nodes or edges (or both). This library includes
20
23
  some of the state-of-the-art algorithms for decomposition, visualization and analysis of such networks.
@@ -51,8 +51,9 @@ For detailed documentation, see: https://skblaz.github.io/py3plex/
51
51
  """
52
52
 
53
53
  # Version information
54
- __version__ = "2.0.1"
55
- __api_version__ = "2.0.1"
54
+ from ._version import __version__
55
+
56
+ __api_version__ = __version__
56
57
 
57
58
  from py3plex.core.multinet import multi_layer_network
58
59
  from py3plex.core.types import (
@@ -0,0 +1,101 @@
1
+ """Evaluate the small expression language used by filters and dynamics rules."""
2
+
3
+ import ast
4
+ import operator
5
+ from numbers import Real
6
+ from typing import Any, Mapping
7
+
8
+
9
+ _BINARY = {
10
+ ast.Add: operator.add,
11
+ ast.Sub: operator.sub,
12
+ ast.Mult: operator.mul,
13
+ ast.Div: operator.truediv,
14
+ ast.FloorDiv: operator.floordiv,
15
+ ast.Mod: operator.mod,
16
+ ast.Pow: operator.pow,
17
+ }
18
+ _UNARY = {
19
+ ast.Not: operator.not_,
20
+ ast.UAdd: operator.pos,
21
+ ast.USub: operator.neg,
22
+ }
23
+ _COMPARE = {
24
+ ast.Eq: operator.eq,
25
+ ast.NotEq: operator.ne,
26
+ ast.Lt: operator.lt,
27
+ ast.LtE: operator.le,
28
+ ast.Gt: operator.gt,
29
+ ast.GtE: operator.ge,
30
+ ast.In: lambda left, right: left in right,
31
+ ast.NotIn: lambda left, right: left not in right,
32
+ ast.Is: operator.is_,
33
+ ast.IsNot: operator.is_not,
34
+ }
35
+
36
+
37
+ def evaluate_expression(expr: str, context: Mapping[str, Any], *, arithmetic_only: bool = False) -> Any:
38
+ """Interpret literals, names, arithmetic, and optionally comparisons/booleans.
39
+
40
+ Calls, attributes, indexing, comprehensions, and arbitrary Python code are
41
+ outside this language. Unknown names raise ValueError.
42
+ """
43
+ try:
44
+ tree = ast.parse(expr, mode="eval")
45
+ except SyntaxError as exc:
46
+ raise ValueError(f"Invalid expression syntax: {exc}") from exc
47
+
48
+ def visit(node: ast.AST) -> Any:
49
+ if isinstance(node, ast.Expression):
50
+ return visit(node.body)
51
+ if isinstance(node, ast.Constant):
52
+ if arithmetic_only and (isinstance(node.value, bool) or not isinstance(node.value, (int, float))):
53
+ raise ValueError("Arithmetic expressions require numeric literals")
54
+ return node.value
55
+ if isinstance(node, ast.Name):
56
+ if node.id not in context:
57
+ raise ValueError(f"Unknown expression name: {node.id}")
58
+ value = context[node.id]
59
+ if arithmetic_only and not isinstance(value, Real):
60
+ raise ValueError(f"Arithmetic expression name {node.id} must be numeric")
61
+ return value
62
+ if isinstance(node, ast.BinOp) and type(node.op) in _BINARY:
63
+ return _BINARY[type(node.op)](visit(node.left), visit(node.right))
64
+ if isinstance(node, ast.UnaryOp) and type(node.op) in _UNARY:
65
+ if arithmetic_only and isinstance(node.op, ast.Not):
66
+ raise ValueError("Boolean operations are not allowed in arithmetic expressions")
67
+ return _UNARY[type(node.op)](visit(node.operand))
68
+ if not arithmetic_only and isinstance(node, ast.BoolOp):
69
+ if isinstance(node.op, ast.And):
70
+ value = True
71
+ for item in node.values:
72
+ value = visit(item)
73
+ if not value:
74
+ return value
75
+ return value
76
+ if isinstance(node.op, ast.Or):
77
+ value = False
78
+ for item in node.values:
79
+ value = visit(item)
80
+ if value:
81
+ return value
82
+ return value
83
+ if not arithmetic_only and isinstance(node, ast.Compare):
84
+ left = visit(node.left)
85
+ for op, comparator in zip(node.ops, node.comparators):
86
+ operation = _COMPARE.get(type(op))
87
+ if operation is None:
88
+ raise ValueError(f"Expression contains disallowed construct: {type(op).__name__}")
89
+ right = visit(comparator)
90
+ if not operation(left, right):
91
+ return False
92
+ left = right
93
+ return True
94
+ raise ValueError(f"Expression contains disallowed construct: {type(node).__name__}")
95
+
96
+ try:
97
+ return visit(tree)
98
+ except ValueError:
99
+ raise
100
+ except Exception as exc:
101
+ raise ValueError(f"Error evaluating expression: {exc}") from exc
@@ -0,0 +1,3 @@
1
+ """Single source for py3plex release version metadata."""
2
+
3
+ __version__ = "2.0.8"
@@ -455,6 +455,7 @@ def _evaluate_algorithms(
455
455
  from py3plex.algorithms.community_detection.multilayer_quality_metrics import (
456
456
  replica_consistency,
457
457
  layer_entropy,
458
+ mdl_score,
458
459
  )
459
460
 
460
461
  import inspect
@@ -519,9 +520,7 @@ def _evaluate_algorithms(
519
520
  value = 0.0
520
521
 
521
522
  elif metric_name == "mdl":
522
- # Description length (if available)
523
- # Placeholder for now
524
- value = 0.0
523
+ value = mdl_score(partition, network)
525
524
 
526
525
  elif metric_name == "replica_consistency":
527
526
  # Multilayer coherence metric
@@ -187,7 +187,7 @@ def modularity(partition: Dict, graph: nx.Graph, weight: str = "weight") -> floa
187
187
 
188
188
  References
189
189
  ----------
190
- .. 1. Newman, M.E.J. & Girvan, M. Finding and evaluating community
190
+ [1] Newman, M.E.J. & Girvan, M. Finding and evaluating community
191
191
  structure in networks. Physical Review E 69, 26113(2004).
192
192
 
193
193
  Examples
@@ -274,7 +274,7 @@ def best_partition(
274
274
 
275
275
  References
276
276
  ----------
277
- .. 1. Blondel, V.D. et al. Fast unfolding of communities in
277
+ [1] Blondel, V.D. et al. Fast unfolding of communities in
278
278
  large networks. J. Stat. Mech 10008, 1-12(2008).
279
279
 
280
280
  Examples
@@ -357,7 +357,7 @@ def generate_dendrogram(
357
357
 
358
358
  References
359
359
  ----------
360
- .. 1. Blondel, V.D. et al. Fast unfolding of communities in large
360
+ [1] Blondel, V.D. et al. Fast unfolding of communities in large
361
361
  networks. J. Stat. Mech 10008, 1-12(2008).
362
362
 
363
363
  Examples
@@ -16,8 +16,8 @@ Both algorithms use:
16
16
 
17
17
  References
18
18
  ----------
19
- .. [1] Label Propagation and Complex Networks (various sources)
20
- .. [2] Multilayer network community detection literature
19
+ [1] Label Propagation and Complex Networks (various sources)
20
+ [2] Multilayer network community detection literature
21
21
  """
22
22
 
23
23
  from __future__ import annotations
@@ -96,7 +96,7 @@ def multilayer_label_propagation_supra(
96
96
 
97
97
  Notes
98
98
  -----
99
- Complexity: O(max_iter * (|E| + omega * L * |V|)) where E is edges, L layers, V nodes
99
+ Complexity: O(max_iter * (\\|E\\| + omega * L * \\|V\\|)) where E is edges, L layers, V nodes
100
100
  """
101
101
  # Validate parameters
102
102
  if omega < 0:
@@ -331,7 +331,7 @@ def multiplex_label_propagation_consensus(
331
331
 
332
332
  Notes
333
333
  -----
334
- Complexity: O(max_iter * inner_max_iter * |E|) where E is edges
334
+ Complexity: O(max_iter * inner_max_iter * \\|E\\|) where E is edges
335
335
  """
336
336
  # Validate parameters
337
337
  if max_iter < 1:
@@ -0,0 +1,353 @@
1
+ """
2
+ MDL Metric Benchmark on Synthetic Multilayer LFR Graphs.
3
+
4
+ Unit tests (see ``tests/test_mdl_score.py``) check that ``mdl_score`` behaves
5
+ correctly on hand-built toy graphs, but they cannot show that the metric is
6
+ actually a *useful* community-quality signal. This module answers that with
7
+ an empirical benchmark against known ground truth:
8
+
9
+ - Generate multilayer LFR graphs across a range of mixing parameters ``mu``
10
+ (easy -> hard).
11
+ - On each graph, score three partitions -- the ground truth, a corrupted/
12
+ degenerate partition, and the output of a real algorithm (Louvain) -- with
13
+ ``mdl_score`` and the baseline metrics ``multilayer_modularity`` and
14
+ ``replica_consistency``.
15
+ - Check whether ``mdl_score`` ranks ground truth best as ``mu`` grows, how
16
+ its ranking agrees (or informatively disagrees) with modularity's, and how
17
+ its compute cost compares to the baselines' on the same graphs.
18
+
19
+ Algorithm choice: this uses ``community_louvain.best_partition`` (run on the
20
+ flat supra-graph, i.e. treating each ``(node, layer)`` pair as an opaque
21
+ node id) rather than this package's own ``leiden_multilayer``/
22
+ ``louvain_multilayer``. Both of the latter are single-level greedy local
23
+ search with no hierarchical aggregation/coarsening phase, so they reliably
24
+ get stuck in a poor local optimum on anything past toy-sized graphs
25
+ (confirmed by hand-stepping the local-move loop -- e.g. on a 2-layer,
26
+ 2-clique graph with default interlayer coupling they converge to a
27
+ half-merged partition with modularity 0.03 instead of the true ~0.5).
28
+ ``community_louvain.best_partition`` implements the real multi-level
29
+ Louvain (with ``generate_dendrogram``/``induced_graph`` aggregation) and
30
+ was verified to recover ground-truth-comparable modularity on the LFR
31
+ graphs here; that upstream local-optimum issue is a separate, unrelated bug
32
+ worth fixing on its own.
33
+ """
34
+
35
+ from collections import defaultdict
36
+ from dataclasses import dataclass
37
+ from typing import Any, Dict, List, Sequence, Tuple
38
+ import time
39
+ import warnings
40
+
41
+ import numpy as np
42
+ from scipy.stats import spearmanr
43
+
44
+ from py3plex.algorithms.community_detection.community_louvain import (
45
+ best_partition,
46
+ )
47
+ from py3plex.algorithms.community_detection.multilayer_benchmark import (
48
+ generate_multilayer_lfr,
49
+ )
50
+ from py3plex.algorithms.community_detection.multilayer_modularity import (
51
+ multilayer_modularity,
52
+ )
53
+ from py3plex.algorithms.community_detection.multilayer_quality_metrics import (
54
+ mdl_score,
55
+ replica_consistency,
56
+ )
57
+
58
+ NodeLayer = Tuple[Any, Any]
59
+ Partition = Dict[NodeLayer, int]
60
+
61
+
62
+ @dataclass
63
+ class PartitionScore:
64
+ """Scores for one (mu, seed, partition_type) combination."""
65
+
66
+ mu: float
67
+ seed: int
68
+ n_nodes: int
69
+ n_edges: int
70
+ partition_type: str # "ground_truth" | "corrupted" | "louvain"
71
+ mdl: float
72
+ modularity: float
73
+ replica_consistency: float
74
+ mdl_time_s: float
75
+ modularity_time_s: float
76
+ rc_time_s: float
77
+
78
+
79
+ def _flatten_ground_truth(communities: Dict[NodeLayer, set]) -> Partition:
80
+ """Collapse each node-layer's community *set* to one representative label.
81
+
82
+ ``generate_multilayer_lfr`` returns overlapping-community sets; with the
83
+ default ``overlapping_nodes=0`` every set is a singleton, so taking the
84
+ min element is a lossless, deterministic flattening to the plain
85
+ ``(node, layer) -> community_id`` format ``mdl_score``/``multilayer_modularity``/
86
+ ``replica_consistency`` all expect.
87
+ """
88
+ return {node_layer: min(coms) for node_layer, coms in communities.items()}
89
+
90
+
91
+ def _corrupt_partition(
92
+ partition: Partition, corruption_rate: float, seed: int
93
+ ) -> Partition:
94
+ """Randomly reassign a fraction of node-layer pairs to a different label.
95
+
96
+ A stand-in for a "degenerate" partition: same node coverage and label
97
+ vocabulary as the input, but a chunk of nodes scattered into the wrong
98
+ community.
99
+ """
100
+ rng = np.random.RandomState(seed)
101
+ labels = sorted(set(partition.values()))
102
+ keys = list(partition.keys())
103
+ n_corrupt = int(len(keys) * corruption_rate)
104
+ corrupt_idx = rng.choice(len(keys), size=n_corrupt, replace=False)
105
+
106
+ corrupted = dict(partition)
107
+ for idx in corrupt_idx:
108
+ key = keys[idx]
109
+ current = corrupted[key]
110
+ choices = [label for label in labels if label != current] or labels
111
+ corrupted[key] = rng.choice(choices)
112
+ return corrupted
113
+
114
+
115
+ def _louvain_partition(network: Any, resolution: float) -> Partition:
116
+ """Run real multi-level Louvain on the flat supra-graph.
117
+
118
+ ``network.core_network`` already has ``(node, layer)`` tuples as node
119
+ ids, so ``best_partition`` naturally treats each node-layer pair as its
120
+ own unit -- this is what makes it usable as a multilayer "real
121
+ algorithm" partition without any extra flattening/expansion step.
122
+ """
123
+ return best_partition(network.core_network, resolution=resolution)
124
+
125
+
126
+ def _score_partition(
127
+ partition: Partition, network: Any
128
+ ) -> Tuple[float, float, float, float, float, float]:
129
+ """Return (mdl, modularity, replica_consistency, mdl_s, modularity_s, rc_s)."""
130
+ t0 = time.perf_counter()
131
+ with warnings.catch_warnings():
132
+ # mdl_score warns on partial/parallel/weighted inputs; none of that
133
+ # is a bug here, so it would just be report noise.
134
+ warnings.simplefilter("ignore")
135
+ mdl = mdl_score(partition, network)
136
+ t1 = time.perf_counter()
137
+
138
+ mod = multilayer_modularity(network, partition)
139
+ t2 = time.perf_counter()
140
+
141
+ rc = replica_consistency(partition, network)
142
+ t3 = time.perf_counter()
143
+
144
+ return mdl, mod, rc, (t1 - t0), (t2 - t1), (t3 - t2)
145
+
146
+
147
+ def run_benchmark(
148
+ mu_values: Sequence[float] = (0.05, 0.1, 0.2, 0.3, 0.4, 0.5),
149
+ ns: Sequence[int] = (200,),
150
+ layers: Sequence[str] = ("L1", "L2", "L3"),
151
+ avg_degree: float = 10.0,
152
+ min_community: int = 20,
153
+ seeds: Sequence[int] = (0, 1, 2),
154
+ corruption_rate: float = 0.3,
155
+ resolution: float = 1.0,
156
+ ) -> List[PartitionScore]:
157
+ """Score ground-truth/corrupted/Louvain partitions across an LFR ``mu`` sweep.
158
+
159
+ Args:
160
+ mu_values: LFR mixing parameters to sweep (0 = perfect communities,
161
+ 1 = random -- i.e. easy to hard).
162
+ ns: Graph sizes (node counts) to sweep. Pass more than one value to
163
+ get a scaling curve for metric compute cost.
164
+ layers: Layer names for the generated multiplex graph.
165
+ avg_degree: Average per-layer degree passed to ``generate_multilayer_lfr``.
166
+ min_community: Minimum community size passed to ``generate_multilayer_lfr``.
167
+ seeds: Random seeds; each is used both for graph generation and for
168
+ the corrupted-partition randomness, so results are reproducible
169
+ per (mu, n, seed).
170
+ corruption_rate: Fraction of node-layer pairs reassigned to a wrong
171
+ community in the corrupted partition.
172
+ resolution: Passed to ``community_louvain.best_partition``.
173
+
174
+ Returns:
175
+ One ``PartitionScore`` per (mu, n, seed, partition_type) combination.
176
+ """
177
+ records: List[PartitionScore] = []
178
+
179
+ for n in ns:
180
+ for mu in mu_values:
181
+ for seed in seeds:
182
+ network, gt_sets = generate_multilayer_lfr(
183
+ n=n,
184
+ layers=list(layers),
185
+ mu=mu,
186
+ avg_degree=avg_degree,
187
+ min_community=min_community,
188
+ seed=seed,
189
+ )
190
+ ground_truth = _flatten_ground_truth(gt_sets)
191
+ n_nodes = network.core_network.number_of_nodes()
192
+ n_edges = network.core_network.number_of_edges()
193
+
194
+ partitions: Dict[str, Partition] = {
195
+ "ground_truth": ground_truth,
196
+ "corrupted": _corrupt_partition(
197
+ ground_truth, corruption_rate, seed
198
+ ),
199
+ "louvain": _louvain_partition(network, resolution),
200
+ }
201
+
202
+ for partition_type, partition in partitions.items():
203
+ mdl, mod, rc, t_mdl, t_mod, t_rc = _score_partition(
204
+ partition, network
205
+ )
206
+ records.append(
207
+ PartitionScore(
208
+ mu=mu,
209
+ seed=seed,
210
+ n_nodes=n_nodes,
211
+ n_edges=n_edges,
212
+ partition_type=partition_type,
213
+ mdl=mdl,
214
+ modularity=mod,
215
+ replica_consistency=rc,
216
+ mdl_time_s=t_mdl,
217
+ modularity_time_s=t_mod,
218
+ rc_time_s=t_rc,
219
+ )
220
+ )
221
+
222
+ return records
223
+
224
+
225
+ def ranking_agreement_report(records: List[PartitionScore]) -> Dict[str, Any]:
226
+ """Check whether ``mdl_score`` ranks ground truth best, and agrees with modularity.
227
+
228
+ Returns:
229
+ Dict with:
230
+ - ``ground_truth_best_rate``: fraction of (mu, n, seed) groups where
231
+ ground truth got the lowest (best) MDL score among the three
232
+ partitions.
233
+ - ``mean_spearman_by_mu``: mean Spearman correlation, per ``mu``,
234
+ between the MDL ranking and the modularity ranking of the three
235
+ partitions in each group (1.0 = full agreement, negative = MDL
236
+ flags something modularity doesn't).
237
+ - ``disagreements``: groups where MDL and modularity disagree on
238
+ which partition is best -- the interesting case where MDL might be
239
+ catching a degenerate partition that modularity misses.
240
+ """
241
+ groups: Dict[Tuple[float, int, int], List[PartitionScore]] = defaultdict(list)
242
+ for r in records:
243
+ groups[(r.mu, r.n_nodes, r.seed)].append(r)
244
+
245
+ gt_best_count = 0
246
+ spearman_per_mu: Dict[float, List[float]] = defaultdict(list)
247
+ disagreements: List[Dict[str, Any]] = []
248
+
249
+ for (mu, n_nodes, seed), group in groups.items():
250
+ by_type = {r.partition_type: r for r in group}
251
+ mdl_vals = [r.mdl for r in group]
252
+ if by_type["ground_truth"].mdl == min(mdl_vals):
253
+ gt_best_count += 1
254
+
255
+ if len(group) >= 2:
256
+ # Lower MDL = better; higher modularity = better, so negate
257
+ # modularity to compare both rankings in the same direction.
258
+ rho, _ = spearmanr(
259
+ [r.mdl for r in group], [-r.modularity for r in group]
260
+ )
261
+ spearman_per_mu[mu].append(rho)
262
+
263
+ mdl_best = min(group, key=lambda r: r.mdl).partition_type
264
+ mod_best = max(group, key=lambda r: r.modularity).partition_type
265
+ if mdl_best != mod_best:
266
+ disagreements.append(
267
+ {
268
+ "mu": mu,
269
+ "n_nodes": n_nodes,
270
+ "seed": seed,
271
+ "mdl_best": mdl_best,
272
+ "modularity_best": mod_best,
273
+ "scores": {
274
+ r.partition_type: {
275
+ "mdl": r.mdl,
276
+ "modularity": r.modularity,
277
+ }
278
+ for r in group
279
+ },
280
+ }
281
+ )
282
+
283
+ n_groups = len(groups)
284
+ return {
285
+ "ground_truth_best_rate": gt_best_count / n_groups if n_groups else float("nan"),
286
+ "mean_spearman_by_mu": {
287
+ mu: float(np.nanmean(vals)) for mu, vals in sorted(spearman_per_mu.items())
288
+ },
289
+ "disagreements": disagreements,
290
+ }
291
+
292
+
293
+ def scaling_report(records: List[PartitionScore]) -> Dict[int, Dict[str, float]]:
294
+ """Average per-metric compute time (seconds), grouped by graph size."""
295
+ by_size: Dict[int, Dict[str, List[float]]] = defaultdict(lambda: defaultdict(list))
296
+ for r in records:
297
+ by_size[r.n_nodes]["mdl_score"].append(r.mdl_time_s)
298
+ by_size[r.n_nodes]["multilayer_modularity"].append(r.modularity_time_s)
299
+ by_size[r.n_nodes]["replica_consistency"].append(r.rc_time_s)
300
+
301
+ return {
302
+ n_nodes: {metric: float(np.mean(times)) for metric, times in metrics.items()}
303
+ for n_nodes, metrics in sorted(by_size.items())
304
+ }
305
+
306
+
307
+ def print_report(records: List[PartitionScore]) -> None:
308
+ """Print a human-readable summary: ranking agreement + scaling."""
309
+ ranking = ranking_agreement_report(records)
310
+ scaling = scaling_report(records)
311
+
312
+ print("=" * 72)
313
+ print("MDL METRIC BENCHMARK REPORT")
314
+ print("=" * 72)
315
+
316
+ print(
317
+ f"\nGround truth ranked best (lowest MDL) in "
318
+ f"{ranking['ground_truth_best_rate']:.1%} of (mu, n, seed) groups"
319
+ )
320
+
321
+ print("\nMDL vs. modularity ranking agreement (Spearman rho) by mu:")
322
+ for mu, rho in ranking["mean_spearman_by_mu"].items():
323
+ print(f" mu={mu:.2f}: rho={rho:+.3f}")
324
+
325
+ if ranking["disagreements"]:
326
+ print(
327
+ f"\n{len(ranking['disagreements'])} group(s) where MDL and "
328
+ "modularity pick a different 'best' partition:"
329
+ )
330
+ for d in ranking["disagreements"]:
331
+ print(
332
+ f" mu={d['mu']:.2f} n={d['n_nodes']} seed={d['seed']}: "
333
+ f"mdl picks '{d['mdl_best']}', modularity picks "
334
+ f"'{d['modularity_best']}'"
335
+ )
336
+ else:
337
+ print("\nNo disagreements between MDL's and modularity's top pick.")
338
+
339
+ print("\nMean metric compute time (seconds) by graph size:")
340
+ header = f" {'n_nodes':>10} {'mdl_score':>12} {'modularity':>12} {'replica_consistency':>20}"
341
+ print(header)
342
+ for n_nodes, metrics in scaling.items():
343
+ print(
344
+ f" {n_nodes:>10} {metrics['mdl_score']:>12.4f} "
345
+ f"{metrics['multilayer_modularity']:>12.4f} "
346
+ f"{metrics['replica_consistency']:>20.4f}"
347
+ )
348
+ print("=" * 72)
349
+
350
+
351
+ if __name__ == "__main__":
352
+ results = run_benchmark()
353
+ print_report(results)