tnfr 4.5.1__tar.gz → 6.0.0__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.

Potentially problematic release.


This version of tnfr might be problematic. Click here for more details.

Files changed (206) hide show
  1. tnfr-6.0.0/PKG-INFO +135 -0
  2. tnfr-6.0.0/README.md +86 -0
  3. tnfr-6.0.0/pyproject.toml +115 -0
  4. tnfr-6.0.0/src/tnfr/__init__.py +270 -0
  5. tnfr-6.0.0/src/tnfr/__init__.pyi +40 -0
  6. tnfr-6.0.0/src/tnfr/_compat.py +11 -0
  7. tnfr-6.0.0/src/tnfr/_version.py +7 -0
  8. tnfr-6.0.0/src/tnfr/_version.pyi +7 -0
  9. tnfr-6.0.0/src/tnfr/alias.py +631 -0
  10. tnfr-6.0.0/src/tnfr/alias.pyi +140 -0
  11. tnfr-6.0.0/src/tnfr/cache.py +732 -0
  12. tnfr-6.0.0/src/tnfr/cache.pyi +232 -0
  13. tnfr-6.0.0/src/tnfr/callback_utils.py +381 -0
  14. tnfr-6.0.0/src/tnfr/callback_utils.pyi +105 -0
  15. tnfr-6.0.0/src/tnfr/cli/__init__.py +89 -0
  16. tnfr-6.0.0/src/tnfr/cli/__init__.pyi +47 -0
  17. tnfr-6.0.0/src/tnfr/cli/arguments.py +199 -0
  18. tnfr-6.0.0/src/tnfr/cli/arguments.pyi +33 -0
  19. tnfr-6.0.0/src/tnfr/cli/execution.py +322 -0
  20. tnfr-6.0.0/src/tnfr/cli/execution.pyi +80 -0
  21. tnfr-6.0.0/src/tnfr/cli/utils.py +34 -0
  22. tnfr-6.0.0/src/tnfr/cli/utils.pyi +8 -0
  23. tnfr-6.0.0/src/tnfr/config/__init__.py +12 -0
  24. tnfr-6.0.0/src/tnfr/config/__init__.pyi +8 -0
  25. tnfr-6.0.0/src/tnfr/config/constants.py +104 -0
  26. tnfr-6.0.0/src/tnfr/config/constants.pyi +12 -0
  27. tnfr-6.0.0/src/tnfr/config/init.py +36 -0
  28. tnfr-6.0.0/src/tnfr/config/init.pyi +8 -0
  29. tnfr-6.0.0/src/tnfr/config/operator_names.py +106 -0
  30. tnfr-6.0.0/src/tnfr/config/operator_names.pyi +28 -0
  31. tnfr-6.0.0/src/tnfr/config/presets.py +104 -0
  32. tnfr-6.0.0/src/tnfr/config/presets.pyi +7 -0
  33. tnfr-6.0.0/src/tnfr/constants/__init__.py +228 -0
  34. tnfr-6.0.0/src/tnfr/constants/__init__.pyi +104 -0
  35. tnfr-6.0.0/src/tnfr/constants/core.py +158 -0
  36. tnfr-6.0.0/src/tnfr/constants/core.pyi +17 -0
  37. tnfr-6.0.0/src/tnfr/constants/init.py +31 -0
  38. tnfr-6.0.0/src/tnfr/constants/init.pyi +12 -0
  39. tnfr-6.0.0/src/tnfr/constants/metric.py +102 -0
  40. tnfr-6.0.0/src/tnfr/constants/metric.pyi +19 -0
  41. tnfr-6.0.0/src/tnfr/constants_glyphs.py +16 -0
  42. tnfr-6.0.0/src/tnfr/constants_glyphs.pyi +12 -0
  43. tnfr-6.0.0/src/tnfr/dynamics/__init__.py +136 -0
  44. tnfr-6.0.0/src/tnfr/dynamics/__init__.pyi +83 -0
  45. tnfr-6.0.0/src/tnfr/dynamics/adaptation.py +201 -0
  46. tnfr-6.0.0/src/tnfr/dynamics/aliases.py +22 -0
  47. tnfr-6.0.0/src/tnfr/dynamics/coordination.py +343 -0
  48. tnfr-6.0.0/src/tnfr/dynamics/dnfr.py +2315 -0
  49. tnfr-6.0.0/src/tnfr/dynamics/dnfr.pyi +33 -0
  50. tnfr-6.0.0/src/tnfr/dynamics/integrators.py +561 -0
  51. tnfr-6.0.0/src/tnfr/dynamics/integrators.pyi +35 -0
  52. tnfr-6.0.0/src/tnfr/dynamics/runtime.py +521 -0
  53. tnfr-6.0.0/src/tnfr/dynamics/sampling.py +34 -0
  54. tnfr-6.0.0/src/tnfr/dynamics/sampling.pyi +7 -0
  55. tnfr-6.0.0/src/tnfr/dynamics/selectors.py +680 -0
  56. tnfr-6.0.0/src/tnfr/execution.py +216 -0
  57. tnfr-6.0.0/src/tnfr/execution.pyi +65 -0
  58. tnfr-6.0.0/src/tnfr/flatten.py +283 -0
  59. tnfr-6.0.0/src/tnfr/flatten.pyi +28 -0
  60. tnfr-6.0.0/src/tnfr/gamma.py +358 -0
  61. tnfr-6.0.0/src/tnfr/gamma.pyi +40 -0
  62. tnfr-6.0.0/src/tnfr/glyph_history.py +337 -0
  63. tnfr-6.0.0/src/tnfr/glyph_history.pyi +53 -0
  64. tnfr-6.0.0/src/tnfr/grammar.py +25 -0
  65. tnfr-6.0.0/src/tnfr/grammar.pyi +13 -0
  66. tnfr-6.0.0/src/tnfr/helpers/__init__.py +151 -0
  67. tnfr-6.0.0/src/tnfr/helpers/__init__.pyi +66 -0
  68. tnfr-6.0.0/src/tnfr/helpers/numeric.py +88 -0
  69. tnfr-6.0.0/src/tnfr/helpers/numeric.pyi +12 -0
  70. tnfr-6.0.0/src/tnfr/immutable.py +214 -0
  71. tnfr-6.0.0/src/tnfr/immutable.pyi +37 -0
  72. tnfr-6.0.0/src/tnfr/initialization.py +199 -0
  73. tnfr-6.0.0/src/tnfr/initialization.pyi +73 -0
  74. tnfr-6.0.0/src/tnfr/io.py +311 -0
  75. tnfr-6.0.0/src/tnfr/io.pyi +11 -0
  76. tnfr-6.0.0/src/tnfr/locking.py +37 -0
  77. tnfr-6.0.0/src/tnfr/locking.pyi +7 -0
  78. tnfr-6.0.0/src/tnfr/metrics/__init__.py +41 -0
  79. tnfr-6.0.0/src/tnfr/metrics/__init__.pyi +20 -0
  80. tnfr-6.0.0/src/tnfr/metrics/coherence.py +1469 -0
  81. tnfr-6.0.0/src/tnfr/metrics/common.py +149 -0
  82. tnfr-6.0.0/src/tnfr/metrics/common.pyi +15 -0
  83. tnfr-6.0.0/src/tnfr/metrics/core.py +259 -0
  84. tnfr-6.0.0/src/tnfr/metrics/core.pyi +13 -0
  85. tnfr-6.0.0/src/tnfr/metrics/diagnosis.py +840 -0
  86. tnfr-6.0.0/src/tnfr/metrics/diagnosis.pyi +89 -0
  87. tnfr-6.0.0/src/tnfr/metrics/export.py +151 -0
  88. tnfr-6.0.0/src/tnfr/metrics/glyph_timing.py +369 -0
  89. tnfr-6.0.0/src/tnfr/metrics/reporting.py +152 -0
  90. tnfr-6.0.0/src/tnfr/metrics/reporting.pyi +12 -0
  91. tnfr-6.0.0/src/tnfr/metrics/sense_index.py +294 -0
  92. tnfr-6.0.0/src/tnfr/metrics/sense_index.pyi +9 -0
  93. tnfr-6.0.0/src/tnfr/metrics/trig.py +216 -0
  94. tnfr-6.0.0/src/tnfr/metrics/trig.pyi +12 -0
  95. tnfr-6.0.0/src/tnfr/metrics/trig_cache.py +105 -0
  96. tnfr-6.0.0/src/tnfr/metrics/trig_cache.pyi +10 -0
  97. tnfr-6.0.0/src/tnfr/node.py +280 -0
  98. tnfr-6.0.0/src/tnfr/node.pyi +161 -0
  99. tnfr-6.0.0/src/tnfr/observers.py +173 -0
  100. tnfr-6.0.0/src/tnfr/observers.pyi +46 -0
  101. tnfr-6.0.0/src/tnfr/ontosim.py +141 -0
  102. tnfr-6.0.0/src/tnfr/ontosim.pyi +33 -0
  103. tnfr-6.0.0/src/tnfr/operators/__init__.py +452 -0
  104. tnfr-6.0.0/src/tnfr/operators/__init__.pyi +31 -0
  105. tnfr-6.0.0/src/tnfr/operators/definitions.py +181 -0
  106. tnfr-6.0.0/src/tnfr/operators/definitions.pyi +92 -0
  107. tnfr-6.0.0/src/tnfr/operators/jitter.py +266 -0
  108. tnfr-6.0.0/src/tnfr/operators/jitter.pyi +11 -0
  109. tnfr-6.0.0/src/tnfr/operators/registry.py +80 -0
  110. tnfr-6.0.0/src/tnfr/operators/registry.pyi +15 -0
  111. tnfr-6.0.0/src/tnfr/operators/remesh.py +569 -0
  112. tnfr-6.0.0/src/tnfr/presets.py +15 -0
  113. tnfr-6.0.0/src/tnfr/presets.pyi +7 -0
  114. tnfr-6.0.0/src/tnfr/py.typed +0 -0
  115. tnfr-6.0.0/src/tnfr/rng.py +440 -0
  116. tnfr-6.0.0/src/tnfr/rng.pyi +14 -0
  117. tnfr-6.0.0/src/tnfr/selector.py +217 -0
  118. tnfr-6.0.0/src/tnfr/selector.pyi +19 -0
  119. tnfr-6.0.0/src/tnfr/sense.py +365 -0
  120. tnfr-6.0.0/src/tnfr/sense.pyi +30 -0
  121. tnfr-6.0.0/src/tnfr/structural.py +106 -0
  122. tnfr-6.0.0/src/tnfr/structural.pyi +46 -0
  123. tnfr-6.0.0/src/tnfr/telemetry/__init__.py +13 -0
  124. tnfr-6.0.0/src/tnfr/telemetry/verbosity.py +37 -0
  125. tnfr-6.0.0/src/tnfr/tokens.py +61 -0
  126. tnfr-6.0.0/src/tnfr/tokens.pyi +41 -0
  127. tnfr-6.0.0/src/tnfr/trace.py +559 -0
  128. tnfr-6.0.0/src/tnfr/trace.pyi +68 -0
  129. tnfr-6.0.0/src/tnfr/types.py +383 -0
  130. tnfr-6.0.0/src/tnfr/types.pyi +145 -0
  131. tnfr-6.0.0/src/tnfr/utils/__init__.py +158 -0
  132. tnfr-6.0.0/src/tnfr/utils/__init__.pyi +133 -0
  133. tnfr-6.0.0/src/tnfr/utils/cache.py +755 -0
  134. tnfr-6.0.0/src/tnfr/utils/cache.pyi +156 -0
  135. tnfr-6.0.0/src/tnfr/utils/data.py +267 -0
  136. tnfr-6.0.0/src/tnfr/utils/data.pyi +73 -0
  137. tnfr-6.0.0/src/tnfr/utils/graph.py +87 -0
  138. tnfr-6.0.0/src/tnfr/utils/graph.pyi +10 -0
  139. tnfr-6.0.0/src/tnfr/utils/init.py +746 -0
  140. tnfr-6.0.0/src/tnfr/utils/init.pyi +85 -0
  141. tnfr-6.0.0/src/tnfr/utils/io.py +157 -0
  142. tnfr-6.0.0/src/tnfr/utils/io.pyi +10 -0
  143. tnfr-6.0.0/src/tnfr/utils/validators.py +130 -0
  144. tnfr-6.0.0/src/tnfr/utils/validators.pyi +19 -0
  145. tnfr-6.0.0/src/tnfr/validation/__init__.py +25 -0
  146. tnfr-6.0.0/src/tnfr/validation/__init__.pyi +17 -0
  147. tnfr-6.0.0/src/tnfr/validation/compatibility.py +59 -0
  148. tnfr-6.0.0/src/tnfr/validation/compatibility.pyi +8 -0
  149. tnfr-6.0.0/src/tnfr/validation/grammar.py +149 -0
  150. tnfr-6.0.0/src/tnfr/validation/grammar.pyi +11 -0
  151. tnfr-6.0.0/src/tnfr/validation/rules.py +194 -0
  152. tnfr-6.0.0/src/tnfr/validation/rules.pyi +18 -0
  153. tnfr-6.0.0/src/tnfr/validation/syntax.py +151 -0
  154. tnfr-6.0.0/src/tnfr/validation/syntax.pyi +7 -0
  155. tnfr-6.0.0/src/tnfr.egg-info/PKG-INFO +135 -0
  156. tnfr-6.0.0/src/tnfr.egg-info/SOURCES.txt +160 -0
  157. tnfr-6.0.0/src/tnfr.egg-info/requires.txt +29 -0
  158. tnfr-4.5.1/PKG-INFO +0 -221
  159. tnfr-4.5.1/README.md +0 -194
  160. tnfr-4.5.1/pyproject.toml +0 -43
  161. tnfr-4.5.1/src/tnfr/__init__.py +0 -90
  162. tnfr-4.5.1/src/tnfr/cli.py +0 -322
  163. tnfr-4.5.1/src/tnfr/config.py +0 -41
  164. tnfr-4.5.1/src/tnfr/constants.py +0 -277
  165. tnfr-4.5.1/src/tnfr/dynamics.py +0 -814
  166. tnfr-4.5.1/src/tnfr/gamma.py +0 -127
  167. tnfr-4.5.1/src/tnfr/grammar.py +0 -155
  168. tnfr-4.5.1/src/tnfr/helpers.py +0 -264
  169. tnfr-4.5.1/src/tnfr/main.py +0 -47
  170. tnfr-4.5.1/src/tnfr/metrics.py +0 -597
  171. tnfr-4.5.1/src/tnfr/node.py +0 -202
  172. tnfr-4.5.1/src/tnfr/observers.py +0 -169
  173. tnfr-4.5.1/src/tnfr/ontosim.py +0 -140
  174. tnfr-4.5.1/src/tnfr/operators.py +0 -525
  175. tnfr-4.5.1/src/tnfr/presets.py +0 -28
  176. tnfr-4.5.1/src/tnfr/program.py +0 -176
  177. tnfr-4.5.1/src/tnfr/scenarios.py +0 -34
  178. tnfr-4.5.1/src/tnfr/sense.py +0 -200
  179. tnfr-4.5.1/src/tnfr/structural.py +0 -201
  180. tnfr-4.5.1/src/tnfr/trace.py +0 -134
  181. tnfr-4.5.1/src/tnfr/types.py +0 -18
  182. tnfr-4.5.1/src/tnfr/validators.py +0 -38
  183. tnfr-4.5.1/src/tnfr.egg-info/PKG-INFO +0 -221
  184. tnfr-4.5.1/src/tnfr.egg-info/SOURCES.txt +0 -47
  185. tnfr-4.5.1/src/tnfr.egg-info/requires.txt +0 -1
  186. tnfr-4.5.1/tests/test_canon.py +0 -30
  187. tnfr-4.5.1/tests/test_cli_sanity.py +0 -12
  188. tnfr-4.5.1/tests/test_edge_cases.py +0 -30
  189. tnfr-4.5.1/tests/test_gamma.py +0 -20
  190. tnfr-4.5.1/tests/test_grammar.py +0 -69
  191. tnfr-4.5.1/tests/test_history.py +0 -15
  192. tnfr-4.5.1/tests/test_history_series.py +0 -27
  193. tnfr-4.5.1/tests/test_integrators.py +0 -36
  194. tnfr-4.5.1/tests/test_invariants.py +0 -89
  195. tnfr-4.5.1/tests/test_nav.py +0 -32
  196. tnfr-4.5.1/tests/test_program.py +0 -17
  197. tnfr-4.5.1/tests/test_remesh.py +0 -50
  198. tnfr-4.5.1/tests/test_remesh_community.py +0 -18
  199. tnfr-4.5.1/tests/test_structural.py +0 -47
  200. tnfr-4.5.1/tests/test_validators.py +0 -38
  201. tnfr-4.5.1/tests/test_vf_coherencia.py +0 -27
  202. {tnfr-4.5.1 → tnfr-6.0.0}/LICENSE.md +0 -0
  203. {tnfr-4.5.1 → tnfr-6.0.0}/setup.cfg +0 -0
  204. {tnfr-4.5.1 → tnfr-6.0.0}/src/tnfr.egg-info/dependency_links.txt +0 -0
  205. {tnfr-4.5.1 → tnfr-6.0.0}/src/tnfr.egg-info/entry_points.txt +0 -0
  206. {tnfr-4.5.1 → tnfr-6.0.0}/src/tnfr.egg-info/top_level.txt +0 -0
tnfr-6.0.0/PKG-INFO ADDED
@@ -0,0 +1,135 @@
1
+ Metadata-Version: 2.4
2
+ Name: tnfr
3
+ Version: 6.0.0
4
+ Summary: Modular structural-based dynamics on networks.
5
+ Author: fmg
6
+ License: MIT
7
+ Project-URL: Homepage, https://pypi.org/project/tnfr/
8
+ Project-URL: Repository, https://github.com/fermga/TNFR-Python-Engine
9
+ Project-URL: GPT, https://chatgpt.com/g/g-67abc78885a88191b2d67f94fd60dc97-tnfr-teoria-de-la-naturaleza-fractal-resonante
10
+ Keywords: TNFR,complex systems,fractals,resonance,networks,structural dynamics,structural analysis
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Intended Audience :: Science/Research
20
+ Classifier: Topic :: Scientific/Engineering
21
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
22
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE.md
26
+ Requires-Dist: networkx>=2.6
27
+ Requires-Dist: cachetools>=5
28
+ Requires-Dist: typing-extensions>=4.4; python_version < "3.10"
29
+ Provides-Extra: numpy
30
+ Requires-Dist: numpy>=1.24; extra == "numpy"
31
+ Provides-Extra: yaml
32
+ Requires-Dist: pyyaml>=6.0; extra == "yaml"
33
+ Provides-Extra: orjson
34
+ Requires-Dist: orjson>=3; extra == "orjson"
35
+ Provides-Extra: test
36
+ Requires-Dist: pytest>=7; extra == "test"
37
+ Requires-Dist: pytest-benchmark>=4; extra == "test"
38
+ Requires-Dist: pydocstyle>=6; extra == "test"
39
+ Requires-Dist: coverage>=7; extra == "test"
40
+ Requires-Dist: flake8>=5; extra == "test"
41
+ Requires-Dist: flake8-pyproject>=1.2; extra == "test"
42
+ Requires-Dist: vulture>=2; extra == "test"
43
+ Provides-Extra: typecheck
44
+ Requires-Dist: mypy>=1.8; extra == "typecheck"
45
+ Requires-Dist: networkx-stubs>=0.0.1; extra == "typecheck"
46
+ Requires-Dist: types-cachetools>=6.0.0.0; extra == "typecheck"
47
+ Requires-Dist: numpy>=1.24; extra == "typecheck"
48
+ Dynamic: license-file
49
+
50
+ # TNFR Python Engine
51
+
52
+ Canonical implementation of the Resonant Fractal Nature Theory (TNFR) for modelling structural
53
+ coherence. The engine seeds resonant nodes, applies structural operators, coordinates
54
+ ΔNFR/phase dynamics, and measures coherence metrics (C(t), Si, νf) without breaking the nodal
55
+ equation $\partial EPI/\partial t = \nu_f \cdot \Delta NFR(t)$.
56
+
57
+ ## Snapshot
58
+
59
+ - **Operate:** build nodes with `tnfr.create_nfr`, execute trajectories via
60
+ `tnfr.structural.run_sequence`, and evolve dynamics with `tnfr.dynamics.run`.
61
+ - **Observe:** register metrics/trace callbacks to capture ΔNFR, C(t), Si, and structural
62
+ histories
63
+ for every run.
64
+ - **Extend:** rely on the canonical operator grammar and invariants before introducing new
65
+ utilities or telemetry.
66
+
67
+ ## Quickstart
68
+
69
+ Install from PyPI (Python ≥ 3.9):
70
+
71
+ ```bash
72
+ pip install tnfr
73
+ ```
74
+
75
+ Then follow the [quickstart guide](docs/getting-started/quickstart.md) for Python and CLI
76
+ walkthroughs plus optional dependency caching helpers.
77
+
78
+ ## Documentation map
79
+
80
+ - [Documentation index](docs/index.md) — navigation hub for API chapters and examples.
81
+ - [API overview](docs/api/overview.md) — package map, invariants, and structural data flow.
82
+ - [Structural operators](docs/api/operators.md) — canonical grammar, key concepts, and typical
83
+ workflows.
84
+ - [Telemetry & utilities](docs/api/telemetry.md) — coherence metrics, trace capture, locking,
85
+ and helper facades.
86
+ - [Examples](docs/examples/README.md) — runnable scenarios, CLI artefacts, and token legend.
87
+
88
+ ## Documentation build workflow
89
+
90
+ Netlify publishes the documentation with [MkDocs](https://www.mkdocs.org/) so the generated
91
+ site preserves the canonical TNFR structure. The same steps can be executed locally:
92
+
93
+ 1. Create and activate a virtual environment (e.g. `python -m venv .venv && source .venv/bin/activate`).
94
+ 2. Install the documentation toolchain: `python -m pip install -r docs/requirements.txt`.
95
+ 3. Preview changes live with `mkdocs serve` or reproduce the Netlify pipeline with
96
+ `mkdocs build`, which writes the static site to the `site/` directory.
97
+
98
+ The Netlify build (`netlify.toml`) runs `python -m pip install -r docs/requirements.txt && mkdocs build`
99
+ and publishes the resulting `site/` directory, ensuring the hosted documentation matches local builds.
100
+
101
+ ## Local development
102
+
103
+ Use the helper scripts to keep formatting aligned with the canonical configuration and to reproduce
104
+ the quality gate locally:
105
+
106
+ ```bash
107
+ ./scripts/format.sh # Apply Black and isort across src/, tests/, scripts/, and benchmarks/
108
+ ./scripts/format.sh --check # Validate formatting without modifying files
109
+ ./scripts/run_tests.sh # Execute the full QA battery (type checks, tests, coverage, linting)
110
+ ```
111
+
112
+ The formatting helper automatically prefers `poetry run` when a Poetry environment is available and
113
+ falls back to `python -m` invocations so local runs mirror the tooling invoked in continuous
114
+ integration.
115
+
116
+ ## Additional resources
117
+
118
+ - [ARCHITECTURE.md](ARCHITECTURE.md) — orchestration layers and invariant enforcement.
119
+ - [CONTRIBUTING.md](CONTRIBUTING.md) — QA battery (`scripts/run_tests.sh`) and review
120
+ expectations.
121
+ - [TNFR.pdf](TNFR.pdf) — theoretical background, structural operators, and paradigm glossary.
122
+
123
+ ## Migration notes
124
+
125
+ - **Si dispersion keys:** Replace any remaining ``dSi_ddisp_fase`` entries in graph payloads
126
+ or configuration files with the English ``dSi_dphase_disp`` key before upgrading. The
127
+ runtime now raises :class:`ValueError` listing any unexpected sensitivity keys, and
128
+ :func:`tnfr.metrics.sense_index.compute_Si_node` rejects unknown keyword arguments.
129
+ - Refer to the [release notes](docs/releases.md#1100-si-dispersion-legacy-keys-removed) for
130
+ a migration snippet that rewrites stored graphs in place prior to running the new version.
131
+
132
+ ## Licensing
133
+
134
+ Released under the [MIT License](LICENSE.md). Cite the TNFR paradigm when publishing research
135
+ or derived artefacts based on this engine.
tnfr-6.0.0/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # TNFR Python Engine
2
+
3
+ Canonical implementation of the Resonant Fractal Nature Theory (TNFR) for modelling structural
4
+ coherence. The engine seeds resonant nodes, applies structural operators, coordinates
5
+ ΔNFR/phase dynamics, and measures coherence metrics (C(t), Si, νf) without breaking the nodal
6
+ equation $\partial EPI/\partial t = \nu_f \cdot \Delta NFR(t)$.
7
+
8
+ ## Snapshot
9
+
10
+ - **Operate:** build nodes with `tnfr.create_nfr`, execute trajectories via
11
+ `tnfr.structural.run_sequence`, and evolve dynamics with `tnfr.dynamics.run`.
12
+ - **Observe:** register metrics/trace callbacks to capture ΔNFR, C(t), Si, and structural
13
+ histories
14
+ for every run.
15
+ - **Extend:** rely on the canonical operator grammar and invariants before introducing new
16
+ utilities or telemetry.
17
+
18
+ ## Quickstart
19
+
20
+ Install from PyPI (Python ≥ 3.9):
21
+
22
+ ```bash
23
+ pip install tnfr
24
+ ```
25
+
26
+ Then follow the [quickstart guide](docs/getting-started/quickstart.md) for Python and CLI
27
+ walkthroughs plus optional dependency caching helpers.
28
+
29
+ ## Documentation map
30
+
31
+ - [Documentation index](docs/index.md) — navigation hub for API chapters and examples.
32
+ - [API overview](docs/api/overview.md) — package map, invariants, and structural data flow.
33
+ - [Structural operators](docs/api/operators.md) — canonical grammar, key concepts, and typical
34
+ workflows.
35
+ - [Telemetry & utilities](docs/api/telemetry.md) — coherence metrics, trace capture, locking,
36
+ and helper facades.
37
+ - [Examples](docs/examples/README.md) — runnable scenarios, CLI artefacts, and token legend.
38
+
39
+ ## Documentation build workflow
40
+
41
+ Netlify publishes the documentation with [MkDocs](https://www.mkdocs.org/) so the generated
42
+ site preserves the canonical TNFR structure. The same steps can be executed locally:
43
+
44
+ 1. Create and activate a virtual environment (e.g. `python -m venv .venv && source .venv/bin/activate`).
45
+ 2. Install the documentation toolchain: `python -m pip install -r docs/requirements.txt`.
46
+ 3. Preview changes live with `mkdocs serve` or reproduce the Netlify pipeline with
47
+ `mkdocs build`, which writes the static site to the `site/` directory.
48
+
49
+ The Netlify build (`netlify.toml`) runs `python -m pip install -r docs/requirements.txt && mkdocs build`
50
+ and publishes the resulting `site/` directory, ensuring the hosted documentation matches local builds.
51
+
52
+ ## Local development
53
+
54
+ Use the helper scripts to keep formatting aligned with the canonical configuration and to reproduce
55
+ the quality gate locally:
56
+
57
+ ```bash
58
+ ./scripts/format.sh # Apply Black and isort across src/, tests/, scripts/, and benchmarks/
59
+ ./scripts/format.sh --check # Validate formatting without modifying files
60
+ ./scripts/run_tests.sh # Execute the full QA battery (type checks, tests, coverage, linting)
61
+ ```
62
+
63
+ The formatting helper automatically prefers `poetry run` when a Poetry environment is available and
64
+ falls back to `python -m` invocations so local runs mirror the tooling invoked in continuous
65
+ integration.
66
+
67
+ ## Additional resources
68
+
69
+ - [ARCHITECTURE.md](ARCHITECTURE.md) — orchestration layers and invariant enforcement.
70
+ - [CONTRIBUTING.md](CONTRIBUTING.md) — QA battery (`scripts/run_tests.sh`) and review
71
+ expectations.
72
+ - [TNFR.pdf](TNFR.pdf) — theoretical background, structural operators, and paradigm glossary.
73
+
74
+ ## Migration notes
75
+
76
+ - **Si dispersion keys:** Replace any remaining ``dSi_ddisp_fase`` entries in graph payloads
77
+ or configuration files with the English ``dSi_dphase_disp`` key before upgrading. The
78
+ runtime now raises :class:`ValueError` listing any unexpected sensitivity keys, and
79
+ :func:`tnfr.metrics.sense_index.compute_Si_node` rejects unknown keyword arguments.
80
+ - Refer to the [release notes](docs/releases.md#1100-si-dispersion-legacy-keys-removed) for
81
+ a migration snippet that rewrites stored graphs in place prior to running the new version.
82
+
83
+ ## Licensing
84
+
85
+ Released under the [MIT License](LICENSE.md). Cite the TNFR paradigm when publishing research
86
+ or derived artefacts based on this engine.
@@ -0,0 +1,115 @@
1
+ [project]
2
+ name = "tnfr"
3
+ dynamic = ["version"]
4
+ description = "Modular structural-based dynamics on networks."
5
+ readme = "README.md"
6
+ requires-python = ">=3.9"
7
+ license = { text = "MIT" }
8
+ authors = [{ name = "fmg" }]
9
+ keywords = [
10
+ "TNFR", "complex systems", "fractals", "resonance",
11
+ "networks", "structural dynamics",
12
+ "structural analysis"
13
+ ]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3 :: Only",
17
+ "Programming Language :: Python :: 3.9",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "License :: OSI Approved :: MIT License",
22
+ "Operating System :: OS Independent",
23
+ "Intended Audience :: Science/Research",
24
+ "Topic :: Scientific/Engineering",
25
+ "Topic :: Scientific/Engineering :: Information Analysis",
26
+ "Topic :: Scientific/Engineering :: Mathematics"
27
+ ]
28
+ dependencies = [
29
+ "networkx>=2.6",
30
+ "cachetools>=5",
31
+ "typing-extensions>=4.4; python_version < \"3.10\"",
32
+ ]
33
+
34
+ [project.optional-dependencies]
35
+ numpy = ["numpy>=1.24"]
36
+ yaml = ["pyyaml>=6.0"]
37
+ orjson = ["orjson>=3"]
38
+ test = [
39
+ "pytest>=7",
40
+ "pytest-benchmark>=4",
41
+ "pydocstyle>=6",
42
+ "coverage>=7",
43
+ "flake8>=5",
44
+ "flake8-pyproject>=1.2",
45
+ "vulture>=2",
46
+ ]
47
+ typecheck = [
48
+ "mypy>=1.8",
49
+ "networkx-stubs>=0.0.1",
50
+ "types-cachetools>=6.0.0.0",
51
+ "numpy>=1.24",
52
+ ]
53
+
54
+ [project.scripts]
55
+ tnfr = "tnfr.cli:main"
56
+
57
+ [project.urls]
58
+ Homepage = "https://pypi.org/project/tnfr/"
59
+ Repository = "https://github.com/fermga/TNFR-Python-Engine"
60
+ GPT = "https://chatgpt.com/g/g-67abc78885a88191b2d67f94fd60dc97-tnfr-teoria-de-la-naturaleza-fractal-resonante"
61
+
62
+ [tool.setuptools.dynamic]
63
+ version = { attr = "tnfr._version.__version__" }
64
+
65
+ [tool.setuptools.package-data]
66
+ tnfr = ["py.typed"]
67
+
68
+ [tool.black]
69
+ line-length = 88
70
+ target-version = ["py39", "py310", "py311", "py312"]
71
+
72
+ [tool.isort]
73
+ profile = "black"
74
+ line_length = 88
75
+ skip = ["benchmarks"]
76
+
77
+ [tool.flake8]
78
+ max-line-length = 88
79
+ ignore = ["E501", "W503"]
80
+ exclude = ["benchmarks/"]
81
+
82
+ [tool.pytest.ini_options]
83
+ pythonpath = ["src"]
84
+ addopts = "-m 'not slow' --benchmark-skip"
85
+ markers = [
86
+ "slow: marks tests as slow (deselect with '-m \"not slow\"')",
87
+ "benchmarks: run with 'pytest benchmarks --benchmark-only' to execute the benchmark suite",
88
+ ]
89
+
90
+ [tool.mypy]
91
+ python_version = "3.10"
92
+ warn_unused_configs = true
93
+ warn_return_any = false
94
+ no_implicit_optional = false
95
+ strict_equality = false
96
+ disallow_any_unimported = false
97
+ show_error_codes = true
98
+ follow_imports = "skip"
99
+ allow_redefinition = true
100
+ allow_untyped_defs = false
101
+ allow_untyped_calls = false
102
+ allow_untyped_globals = false
103
+
104
+ [[tool.mypy.overrides]]
105
+ module = ["networkx", "networkx.*"]
106
+ ignore_missing_imports = true
107
+
108
+ [[tool.mypy.overrides]]
109
+ module = ["yaml", "yaml.*"]
110
+ ignore_missing_imports = true
111
+
112
+
113
+ [build-system]
114
+ requires = ["setuptools>=78.1.1", "wheel"]
115
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,270 @@
1
+ """Minimal public API for :mod:`tnfr`.
2
+
3
+ This package only re-exports a handful of high level helpers. Most
4
+ functionality lives in submodules that should be imported directly, for
5
+ example :mod:`tnfr.metrics`, :mod:`tnfr.observers` or the DSL utilities
6
+ in :mod:`tnfr.tokens`, :mod:`tnfr.flatten` and :mod:`tnfr.execution`.
7
+
8
+ Exported helpers and their dependencies
9
+ ---------------------------------------
10
+ The :data:`EXPORT_DEPENDENCIES` mapping enumerates which internal
11
+ submodules and third-party packages are required to load each helper.
12
+ The imports are grouped as follows:
13
+
14
+ ``step`` / ``run``
15
+ Provided by :mod:`tnfr.dynamics`. These helpers rely on the
16
+ machinery defined within the :mod:`tnfr.dynamics` package (operator
17
+ orchestration, validation hooks and metrics integration) and require
18
+ the ``networkx`` package for graph handling.
19
+
20
+ ``prepare_network``
21
+ Defined in :mod:`tnfr.ontosim`. Besides :mod:`tnfr.ontosim`
22
+ itself, the helper imports :mod:`tnfr.callback_utils`,
23
+ :mod:`tnfr.constants`, :mod:`tnfr.dynamics`, :mod:`tnfr.glyph_history`,
24
+ :mod:`tnfr.initialization` and :mod:`tnfr.utils` to assemble the
25
+ graph preparation pipeline. It also requires ``networkx`` at import
26
+ time.
27
+
28
+ ``create_nfr`` / ``run_sequence``
29
+ Re-exported from :mod:`tnfr.structural`. They depend on
30
+ :mod:`tnfr.structural`, :mod:`tnfr.constants`, :mod:`tnfr.dynamics`,
31
+ :mod:`tnfr.operators.definitions`, :mod:`tnfr.operators.registry` and
32
+ :mod:`tnfr.validation`, and additionally require the ``networkx``
33
+ package.
34
+
35
+ ``cached_import`` and ``prune_failed_imports`` remain available from
36
+ ``tnfr.utils`` for optional dependency management.
37
+ """
38
+
39
+ from __future__ import annotations
40
+
41
+ import warnings
42
+ from importlib import import_module, metadata
43
+ from importlib.metadata import PackageNotFoundError
44
+ from typing import Any, Callable, NoReturn
45
+
46
+
47
+ EXPORT_DEPENDENCIES: dict[str, dict[str, tuple[str, ...]]] = {
48
+ "step": {
49
+ "submodules": ("tnfr.dynamics",),
50
+ "third_party": ("networkx",),
51
+ },
52
+ "run": {
53
+ "submodules": ("tnfr.dynamics",),
54
+ "third_party": ("networkx",),
55
+ },
56
+ "prepare_network": {
57
+ "submodules": (
58
+ "tnfr.ontosim",
59
+ "tnfr.callback_utils",
60
+ "tnfr.constants",
61
+ "tnfr.dynamics",
62
+ "tnfr.glyph_history",
63
+ "tnfr.initialization",
64
+ "tnfr.utils",
65
+ ),
66
+ "third_party": ("networkx",),
67
+ },
68
+ "create_nfr": {
69
+ "submodules": (
70
+ "tnfr.structural",
71
+ "tnfr.constants",
72
+ "tnfr.dynamics",
73
+ "tnfr.operators.definitions",
74
+ "tnfr.operators.registry",
75
+ "tnfr.validation",
76
+ ),
77
+ "third_party": ("networkx",),
78
+ },
79
+ "run_sequence": {
80
+ "submodules": (
81
+ "tnfr.structural",
82
+ "tnfr.constants",
83
+ "tnfr.dynamics",
84
+ "tnfr.operators.definitions",
85
+ "tnfr.operators.registry",
86
+ "tnfr.validation",
87
+ ),
88
+ "third_party": ("networkx",),
89
+ },
90
+ }
91
+
92
+
93
+ try: # pragma: no cover - exercised in version resolution tests
94
+ __version__ = metadata.version("tnfr")
95
+ except PackageNotFoundError: # pragma: no cover - fallback tested explicitly
96
+ from ._version import __version__ as _fallback_version
97
+
98
+ __version__ = _fallback_version
99
+
100
+
101
+ def _is_internal_import_error(exc: ImportError) -> bool:
102
+ missing_name = getattr(exc, "name", None) or ""
103
+ if missing_name.startswith("tnfr"):
104
+ return True
105
+
106
+ module_name = getattr(exc, "module", None) or ""
107
+ if module_name.startswith("tnfr"):
108
+ return True
109
+
110
+ missing_path = getattr(exc, "path", None) or ""
111
+ if missing_path:
112
+ normalized = missing_path.replace("\\", "/")
113
+ if "/tnfr/" in normalized or normalized.endswith("/tnfr"):
114
+ return True
115
+
116
+ message = str(exc)
117
+ lowered = message.lower()
118
+ mentions_base_package = "module 'tnfr'" in lowered or 'module "tnfr"' in lowered
119
+ if ("tnfr." in message or mentions_base_package) and (
120
+ "circular import" in lowered or "partially initialized module" in lowered
121
+ ):
122
+ return True
123
+
124
+ return False
125
+
126
+
127
+ def _missing_dependency(
128
+ name: str, exc: ImportError, *, module: str | None = None
129
+ ) -> Callable[..., NoReturn]:
130
+ missing_name = getattr(exc, "name", None)
131
+
132
+ def _stub(*args: Any, **kwargs: Any) -> NoReturn:
133
+ raise ImportError(
134
+ f"{name} is unavailable because required dependencies could not be imported. "
135
+ f"Original error ({exc.__class__.__name__}): {exc}. "
136
+ "Install the missing packages (e.g. 'networkx' or grammar modules)."
137
+ ) from exc
138
+
139
+ _stub.__tnfr_missing_dependency__ = {
140
+ "export": name,
141
+ "module": module,
142
+ "missing": missing_name,
143
+ }
144
+ return _stub
145
+
146
+
147
+ _MISSING_EXPORTS: dict[str, dict[str, Any]] = {}
148
+
149
+
150
+ class ExportDependencyError(RuntimeError):
151
+ """Raised when the export dependency manifest is inconsistent."""
152
+
153
+
154
+ def _validate_export_dependencies() -> None:
155
+ """Ensure exported helpers and their manifest entries stay in sync."""
156
+
157
+ if "__all__" not in globals():
158
+ # Defensive guard for unusual import orders (should never trigger).
159
+ return
160
+
161
+ issues: list[str] = []
162
+ manifest = EXPORT_DEPENDENCIES
163
+ export_names = [name for name in __all__ if name != "__version__"]
164
+ manifest_names = set(manifest)
165
+
166
+ for export_name in export_names:
167
+ if export_name not in manifest:
168
+ issues.append(
169
+ f"helper '{export_name}' is exported via __all__ but missing from EXPORT_DEPENDENCIES"
170
+ )
171
+ continue
172
+
173
+ entry = manifest[export_name]
174
+ if not isinstance(entry, dict):
175
+ issues.append(
176
+ f"helper '{export_name}' has a malformed manifest entry (expected mapping, got {type(entry)!r})"
177
+ )
178
+ continue
179
+
180
+ for key in ("submodules", "third_party"):
181
+ value = entry.get(key)
182
+ if not value:
183
+ issues.append(
184
+ f"helper '{export_name}' is missing '{key}' dependencies in EXPORT_DEPENDENCIES"
185
+ )
186
+
187
+ missing_exports = manifest_names.difference(export_names).difference(_MISSING_EXPORTS)
188
+ for manifest_only in sorted(missing_exports):
189
+ entry = manifest[manifest_only]
190
+ if not isinstance(entry, dict):
191
+ issues.append(
192
+ f"helper '{manifest_only}' has a malformed manifest entry (expected mapping, got {type(entry)!r})"
193
+ )
194
+ continue
195
+
196
+ for key in ("submodules", "third_party"):
197
+ value = entry.get(key)
198
+ if not value:
199
+ issues.append(
200
+ f"helper '{manifest_only}' is missing '{key}' dependencies in EXPORT_DEPENDENCIES"
201
+ )
202
+
203
+ issues.append(
204
+ f"helper '{manifest_only}' is listed in EXPORT_DEPENDENCIES but not exported via __all__"
205
+ )
206
+
207
+ if issues:
208
+ raise ExportDependencyError(
209
+ "Invalid TNFR export dependency manifest:\n- " + "\n- ".join(issues)
210
+ )
211
+
212
+
213
+ def _assign_exports(module: str, names: tuple[str, ...]) -> bool:
214
+ try: # pragma: no cover - exercised in import tests
215
+ mod = import_module(f".{module}", __name__)
216
+ except ImportError as exc: # pragma: no cover - no missing deps in CI
217
+ if _is_internal_import_error(exc):
218
+ raise
219
+ for export_name in names:
220
+ stub = _missing_dependency(export_name, exc, module=module)
221
+ globals()[export_name] = stub
222
+ _MISSING_EXPORTS[export_name] = getattr(
223
+ stub, "__tnfr_missing_dependency__", {}
224
+ )
225
+ return False
226
+ else:
227
+ for export_name in names:
228
+ globals()[export_name] = getattr(mod, export_name)
229
+ return True
230
+
231
+
232
+ _assign_exports("dynamics", ("step", "run"))
233
+
234
+
235
+ _HAS_PREPARE_NETWORK = _assign_exports("ontosim", ("prepare_network",))
236
+
237
+
238
+ _HAS_RUN_SEQUENCE = _assign_exports("structural", ("create_nfr", "run_sequence"))
239
+
240
+
241
+ def _emit_missing_dependency_warning() -> None:
242
+ if not _MISSING_EXPORTS:
243
+ return
244
+ details = ", ".join(
245
+ f"{name} (missing: {info.get('missing') or 'unknown'})"
246
+ for name, info in sorted(_MISSING_EXPORTS.items())
247
+ )
248
+ warnings.warn(
249
+ "TNFR helpers disabled because dependencies are missing: " + details,
250
+ ImportWarning,
251
+ stacklevel=2,
252
+ )
253
+
254
+
255
+ _emit_missing_dependency_warning()
256
+
257
+
258
+ __all__ = [
259
+ "__version__",
260
+ "step",
261
+ "run",
262
+ "prepare_network",
263
+ "create_nfr",
264
+ ]
265
+
266
+ if _HAS_RUN_SEQUENCE:
267
+ __all__.append("run_sequence")
268
+
269
+
270
+ _validate_export_dependencies()
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Callable
4
+ from typing import Any, NoReturn
5
+
6
+ from .dynamics import run, step
7
+ from .ontosim import prepare_network
8
+ from .structural import create_nfr, run_sequence
9
+
10
+ EXPORT_DEPENDENCIES: dict[str, dict[str, tuple[str, ...]]]
11
+ """Manifest describing required submodules and third-party packages."""
12
+
13
+ _MISSING_EXPORTS: dict[str, dict[str, Any]]
14
+
15
+ __version__: str
16
+ __all__: list[str]
17
+
18
+
19
+ class ExportDependencyError(RuntimeError):
20
+ """Raised when the export dependency manifest is inconsistent."""
21
+
22
+
23
+ def _is_internal_import_error(exc: ImportError) -> bool: ...
24
+
25
+ def _missing_dependency(
26
+ name: str,
27
+ exc: ImportError,
28
+ *,
29
+ module: str | None = ...,
30
+ ) -> Callable[..., NoReturn]: ...
31
+
32
+
33
+ def _validate_export_dependencies() -> None: ...
34
+
35
+ def _assign_exports(module: str, names: tuple[str, ...]) -> bool: ...
36
+
37
+ def _emit_missing_dependency_warning() -> None: ...
38
+
39
+ _HAS_PREPARE_NETWORK: bool
40
+ _HAS_RUN_SEQUENCE: bool
@@ -0,0 +1,11 @@
1
+ """Compatibility helpers for bridging typing features across Python versions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ try: # pragma: no cover - exercised implicitly by importers
6
+ from typing import TypeAlias # type: ignore[attr-defined]
7
+ except (ImportError, AttributeError): # pragma: no cover - Python < 3.10
8
+ from typing_extensions import TypeAlias # type: ignore[assignment]
9
+
10
+ __all__ = ["TypeAlias"]
11
+
@@ -0,0 +1,7 @@
1
+ """Package version for :mod:`tnfr`."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __all__ = ["__version__"]
6
+
7
+ __version__ = "6.0.0"
@@ -0,0 +1,7 @@
1
+ from typing import Any
2
+
3
+ __all__: Any
4
+
5
+ def __getattr__(name: str) -> Any: ...
6
+
7
+ __version__: Any