tnfr 4.5.2__py3-none-any.whl → 8.5.0__py3-none-any.whl

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 (365) hide show
  1. tnfr/__init__.py +334 -50
  2. tnfr/__init__.pyi +33 -0
  3. tnfr/_compat.py +10 -0
  4. tnfr/_generated_version.py +34 -0
  5. tnfr/_version.py +49 -0
  6. tnfr/_version.pyi +7 -0
  7. tnfr/alias.py +214 -37
  8. tnfr/alias.pyi +108 -0
  9. tnfr/backends/__init__.py +354 -0
  10. tnfr/backends/jax_backend.py +173 -0
  11. tnfr/backends/numpy_backend.py +238 -0
  12. tnfr/backends/optimized_numpy.py +420 -0
  13. tnfr/backends/torch_backend.py +408 -0
  14. tnfr/cache.py +149 -556
  15. tnfr/cache.pyi +13 -0
  16. tnfr/cli/__init__.py +51 -16
  17. tnfr/cli/__init__.pyi +26 -0
  18. tnfr/cli/arguments.py +344 -32
  19. tnfr/cli/arguments.pyi +29 -0
  20. tnfr/cli/execution.py +676 -50
  21. tnfr/cli/execution.pyi +70 -0
  22. tnfr/cli/interactive_validator.py +614 -0
  23. tnfr/cli/utils.py +18 -3
  24. tnfr/cli/utils.pyi +7 -0
  25. tnfr/cli/validate.py +236 -0
  26. tnfr/compat/__init__.py +85 -0
  27. tnfr/compat/dataclass.py +136 -0
  28. tnfr/compat/jsonschema_stub.py +61 -0
  29. tnfr/compat/matplotlib_stub.py +73 -0
  30. tnfr/compat/numpy_stub.py +155 -0
  31. tnfr/config/__init__.py +224 -0
  32. tnfr/config/__init__.pyi +10 -0
  33. tnfr/{constants_glyphs.py → config/constants.py} +26 -20
  34. tnfr/config/constants.pyi +12 -0
  35. tnfr/config/defaults.py +54 -0
  36. tnfr/{constants/core.py → config/defaults_core.py} +59 -6
  37. tnfr/config/defaults_init.py +33 -0
  38. tnfr/config/defaults_metric.py +104 -0
  39. tnfr/config/feature_flags.py +81 -0
  40. tnfr/config/feature_flags.pyi +16 -0
  41. tnfr/config/glyph_constants.py +31 -0
  42. tnfr/config/init.py +77 -0
  43. tnfr/config/init.pyi +8 -0
  44. tnfr/config/operator_names.py +254 -0
  45. tnfr/config/operator_names.pyi +36 -0
  46. tnfr/config/physics_derivation.py +354 -0
  47. tnfr/config/presets.py +83 -0
  48. tnfr/config/presets.pyi +7 -0
  49. tnfr/config/security.py +927 -0
  50. tnfr/config/thresholds.py +114 -0
  51. tnfr/config/tnfr_config.py +498 -0
  52. tnfr/constants/__init__.py +51 -133
  53. tnfr/constants/__init__.pyi +92 -0
  54. tnfr/constants/aliases.py +33 -0
  55. tnfr/constants/aliases.pyi +27 -0
  56. tnfr/constants/init.py +3 -1
  57. tnfr/constants/init.pyi +12 -0
  58. tnfr/constants/metric.py +9 -15
  59. tnfr/constants/metric.pyi +19 -0
  60. tnfr/core/__init__.py +33 -0
  61. tnfr/core/container.py +226 -0
  62. tnfr/core/default_implementations.py +329 -0
  63. tnfr/core/interfaces.py +279 -0
  64. tnfr/dynamics/__init__.py +213 -633
  65. tnfr/dynamics/__init__.pyi +83 -0
  66. tnfr/dynamics/adaptation.py +267 -0
  67. tnfr/dynamics/adaptation.pyi +7 -0
  68. tnfr/dynamics/adaptive_sequences.py +189 -0
  69. tnfr/dynamics/adaptive_sequences.pyi +14 -0
  70. tnfr/dynamics/aliases.py +23 -0
  71. tnfr/dynamics/aliases.pyi +19 -0
  72. tnfr/dynamics/bifurcation.py +232 -0
  73. tnfr/dynamics/canonical.py +229 -0
  74. tnfr/dynamics/canonical.pyi +48 -0
  75. tnfr/dynamics/coordination.py +385 -0
  76. tnfr/dynamics/coordination.pyi +25 -0
  77. tnfr/dynamics/dnfr.py +2699 -398
  78. tnfr/dynamics/dnfr.pyi +26 -0
  79. tnfr/dynamics/dynamic_limits.py +225 -0
  80. tnfr/dynamics/feedback.py +252 -0
  81. tnfr/dynamics/feedback.pyi +24 -0
  82. tnfr/dynamics/fused_dnfr.py +454 -0
  83. tnfr/dynamics/homeostasis.py +157 -0
  84. tnfr/dynamics/homeostasis.pyi +14 -0
  85. tnfr/dynamics/integrators.py +496 -102
  86. tnfr/dynamics/integrators.pyi +36 -0
  87. tnfr/dynamics/learning.py +310 -0
  88. tnfr/dynamics/learning.pyi +33 -0
  89. tnfr/dynamics/metabolism.py +254 -0
  90. tnfr/dynamics/nbody.py +796 -0
  91. tnfr/dynamics/nbody_tnfr.py +783 -0
  92. tnfr/dynamics/propagation.py +326 -0
  93. tnfr/dynamics/runtime.py +908 -0
  94. tnfr/dynamics/runtime.pyi +77 -0
  95. tnfr/dynamics/sampling.py +10 -5
  96. tnfr/dynamics/sampling.pyi +7 -0
  97. tnfr/dynamics/selectors.py +711 -0
  98. tnfr/dynamics/selectors.pyi +85 -0
  99. tnfr/dynamics/structural_clip.py +207 -0
  100. tnfr/errors/__init__.py +37 -0
  101. tnfr/errors/contextual.py +492 -0
  102. tnfr/execution.py +77 -55
  103. tnfr/execution.pyi +45 -0
  104. tnfr/extensions/__init__.py +205 -0
  105. tnfr/extensions/__init__.pyi +18 -0
  106. tnfr/extensions/base.py +173 -0
  107. tnfr/extensions/base.pyi +35 -0
  108. tnfr/extensions/business/__init__.py +71 -0
  109. tnfr/extensions/business/__init__.pyi +11 -0
  110. tnfr/extensions/business/cookbook.py +88 -0
  111. tnfr/extensions/business/cookbook.pyi +8 -0
  112. tnfr/extensions/business/health_analyzers.py +202 -0
  113. tnfr/extensions/business/health_analyzers.pyi +9 -0
  114. tnfr/extensions/business/patterns.py +183 -0
  115. tnfr/extensions/business/patterns.pyi +8 -0
  116. tnfr/extensions/medical/__init__.py +73 -0
  117. tnfr/extensions/medical/__init__.pyi +11 -0
  118. tnfr/extensions/medical/cookbook.py +88 -0
  119. tnfr/extensions/medical/cookbook.pyi +8 -0
  120. tnfr/extensions/medical/health_analyzers.py +181 -0
  121. tnfr/extensions/medical/health_analyzers.pyi +9 -0
  122. tnfr/extensions/medical/patterns.py +163 -0
  123. tnfr/extensions/medical/patterns.pyi +8 -0
  124. tnfr/flatten.py +29 -50
  125. tnfr/flatten.pyi +21 -0
  126. tnfr/gamma.py +66 -53
  127. tnfr/gamma.pyi +36 -0
  128. tnfr/glyph_history.py +144 -57
  129. tnfr/glyph_history.pyi +35 -0
  130. tnfr/glyph_runtime.py +19 -0
  131. tnfr/glyph_runtime.pyi +8 -0
  132. tnfr/immutable.py +70 -30
  133. tnfr/immutable.pyi +36 -0
  134. tnfr/initialization.py +22 -16
  135. tnfr/initialization.pyi +65 -0
  136. tnfr/io.py +5 -241
  137. tnfr/io.pyi +13 -0
  138. tnfr/locking.pyi +7 -0
  139. tnfr/mathematics/__init__.py +79 -0
  140. tnfr/mathematics/backend.py +453 -0
  141. tnfr/mathematics/backend.pyi +99 -0
  142. tnfr/mathematics/dynamics.py +408 -0
  143. tnfr/mathematics/dynamics.pyi +90 -0
  144. tnfr/mathematics/epi.py +391 -0
  145. tnfr/mathematics/epi.pyi +65 -0
  146. tnfr/mathematics/generators.py +242 -0
  147. tnfr/mathematics/generators.pyi +29 -0
  148. tnfr/mathematics/metrics.py +119 -0
  149. tnfr/mathematics/metrics.pyi +16 -0
  150. tnfr/mathematics/operators.py +239 -0
  151. tnfr/mathematics/operators.pyi +59 -0
  152. tnfr/mathematics/operators_factory.py +124 -0
  153. tnfr/mathematics/operators_factory.pyi +11 -0
  154. tnfr/mathematics/projection.py +87 -0
  155. tnfr/mathematics/projection.pyi +33 -0
  156. tnfr/mathematics/runtime.py +182 -0
  157. tnfr/mathematics/runtime.pyi +64 -0
  158. tnfr/mathematics/spaces.py +256 -0
  159. tnfr/mathematics/spaces.pyi +83 -0
  160. tnfr/mathematics/transforms.py +305 -0
  161. tnfr/mathematics/transforms.pyi +62 -0
  162. tnfr/metrics/__init__.py +47 -9
  163. tnfr/metrics/__init__.pyi +20 -0
  164. tnfr/metrics/buffer_cache.py +163 -0
  165. tnfr/metrics/buffer_cache.pyi +24 -0
  166. tnfr/metrics/cache_utils.py +214 -0
  167. tnfr/metrics/coherence.py +1510 -330
  168. tnfr/metrics/coherence.pyi +129 -0
  169. tnfr/metrics/common.py +23 -16
  170. tnfr/metrics/common.pyi +35 -0
  171. tnfr/metrics/core.py +251 -36
  172. tnfr/metrics/core.pyi +13 -0
  173. tnfr/metrics/diagnosis.py +709 -110
  174. tnfr/metrics/diagnosis.pyi +86 -0
  175. tnfr/metrics/emergence.py +245 -0
  176. tnfr/metrics/export.py +60 -18
  177. tnfr/metrics/export.pyi +7 -0
  178. tnfr/metrics/glyph_timing.py +233 -43
  179. tnfr/metrics/glyph_timing.pyi +81 -0
  180. tnfr/metrics/learning_metrics.py +280 -0
  181. tnfr/metrics/learning_metrics.pyi +21 -0
  182. tnfr/metrics/phase_coherence.py +351 -0
  183. tnfr/metrics/phase_compatibility.py +349 -0
  184. tnfr/metrics/reporting.py +63 -28
  185. tnfr/metrics/reporting.pyi +25 -0
  186. tnfr/metrics/sense_index.py +1126 -43
  187. tnfr/metrics/sense_index.pyi +9 -0
  188. tnfr/metrics/trig.py +215 -23
  189. tnfr/metrics/trig.pyi +13 -0
  190. tnfr/metrics/trig_cache.py +148 -24
  191. tnfr/metrics/trig_cache.pyi +10 -0
  192. tnfr/multiscale/__init__.py +32 -0
  193. tnfr/multiscale/hierarchical.py +517 -0
  194. tnfr/node.py +646 -140
  195. tnfr/node.pyi +139 -0
  196. tnfr/observers.py +160 -45
  197. tnfr/observers.pyi +31 -0
  198. tnfr/ontosim.py +23 -19
  199. tnfr/ontosim.pyi +28 -0
  200. tnfr/operators/__init__.py +1358 -106
  201. tnfr/operators/__init__.pyi +31 -0
  202. tnfr/operators/algebra.py +277 -0
  203. tnfr/operators/canonical_patterns.py +420 -0
  204. tnfr/operators/cascade.py +267 -0
  205. tnfr/operators/cycle_detection.py +358 -0
  206. tnfr/operators/definitions.py +4108 -0
  207. tnfr/operators/definitions.pyi +78 -0
  208. tnfr/operators/grammar.py +1164 -0
  209. tnfr/operators/grammar.pyi +140 -0
  210. tnfr/operators/hamiltonian.py +710 -0
  211. tnfr/operators/health_analyzer.py +809 -0
  212. tnfr/operators/jitter.py +107 -38
  213. tnfr/operators/jitter.pyi +11 -0
  214. tnfr/operators/lifecycle.py +314 -0
  215. tnfr/operators/metabolism.py +618 -0
  216. tnfr/operators/metrics.py +2138 -0
  217. tnfr/operators/network_analysis/__init__.py +27 -0
  218. tnfr/operators/network_analysis/source_detection.py +186 -0
  219. tnfr/operators/nodal_equation.py +395 -0
  220. tnfr/operators/pattern_detection.py +660 -0
  221. tnfr/operators/patterns.py +669 -0
  222. tnfr/operators/postconditions/__init__.py +38 -0
  223. tnfr/operators/postconditions/mutation.py +236 -0
  224. tnfr/operators/preconditions/__init__.py +1226 -0
  225. tnfr/operators/preconditions/coherence.py +305 -0
  226. tnfr/operators/preconditions/dissonance.py +236 -0
  227. tnfr/operators/preconditions/emission.py +128 -0
  228. tnfr/operators/preconditions/mutation.py +580 -0
  229. tnfr/operators/preconditions/reception.py +125 -0
  230. tnfr/operators/preconditions/resonance.py +364 -0
  231. tnfr/operators/registry.py +74 -0
  232. tnfr/operators/registry.pyi +9 -0
  233. tnfr/operators/remesh.py +1415 -91
  234. tnfr/operators/remesh.pyi +26 -0
  235. tnfr/operators/structural_units.py +268 -0
  236. tnfr/operators/unified_grammar.py +105 -0
  237. tnfr/parallel/__init__.py +54 -0
  238. tnfr/parallel/auto_scaler.py +234 -0
  239. tnfr/parallel/distributed.py +384 -0
  240. tnfr/parallel/engine.py +238 -0
  241. tnfr/parallel/gpu_engine.py +420 -0
  242. tnfr/parallel/monitoring.py +248 -0
  243. tnfr/parallel/partitioner.py +459 -0
  244. tnfr/py.typed +0 -0
  245. tnfr/recipes/__init__.py +22 -0
  246. tnfr/recipes/cookbook.py +743 -0
  247. tnfr/rng.py +75 -151
  248. tnfr/rng.pyi +26 -0
  249. tnfr/schemas/__init__.py +8 -0
  250. tnfr/schemas/grammar.json +94 -0
  251. tnfr/sdk/__init__.py +107 -0
  252. tnfr/sdk/__init__.pyi +19 -0
  253. tnfr/sdk/adaptive_system.py +173 -0
  254. tnfr/sdk/adaptive_system.pyi +21 -0
  255. tnfr/sdk/builders.py +370 -0
  256. tnfr/sdk/builders.pyi +51 -0
  257. tnfr/sdk/fluent.py +1121 -0
  258. tnfr/sdk/fluent.pyi +74 -0
  259. tnfr/sdk/templates.py +342 -0
  260. tnfr/sdk/templates.pyi +41 -0
  261. tnfr/sdk/utils.py +341 -0
  262. tnfr/secure_config.py +46 -0
  263. tnfr/security/__init__.py +70 -0
  264. tnfr/security/database.py +514 -0
  265. tnfr/security/subprocess.py +503 -0
  266. tnfr/security/validation.py +290 -0
  267. tnfr/selector.py +59 -22
  268. tnfr/selector.pyi +19 -0
  269. tnfr/sense.py +92 -67
  270. tnfr/sense.pyi +23 -0
  271. tnfr/services/__init__.py +17 -0
  272. tnfr/services/orchestrator.py +325 -0
  273. tnfr/sparse/__init__.py +39 -0
  274. tnfr/sparse/representations.py +492 -0
  275. tnfr/structural.py +639 -263
  276. tnfr/structural.pyi +83 -0
  277. tnfr/telemetry/__init__.py +35 -0
  278. tnfr/telemetry/cache_metrics.py +226 -0
  279. tnfr/telemetry/cache_metrics.pyi +64 -0
  280. tnfr/telemetry/nu_f.py +422 -0
  281. tnfr/telemetry/nu_f.pyi +108 -0
  282. tnfr/telemetry/verbosity.py +36 -0
  283. tnfr/telemetry/verbosity.pyi +15 -0
  284. tnfr/tokens.py +2 -4
  285. tnfr/tokens.pyi +36 -0
  286. tnfr/tools/__init__.py +20 -0
  287. tnfr/tools/domain_templates.py +478 -0
  288. tnfr/tools/sequence_generator.py +846 -0
  289. tnfr/topology/__init__.py +13 -0
  290. tnfr/topology/asymmetry.py +151 -0
  291. tnfr/trace.py +300 -126
  292. tnfr/trace.pyi +42 -0
  293. tnfr/tutorials/__init__.py +38 -0
  294. tnfr/tutorials/autonomous_evolution.py +285 -0
  295. tnfr/tutorials/interactive.py +1576 -0
  296. tnfr/tutorials/structural_metabolism.py +238 -0
  297. tnfr/types.py +743 -12
  298. tnfr/types.pyi +357 -0
  299. tnfr/units.py +68 -0
  300. tnfr/units.pyi +13 -0
  301. tnfr/utils/__init__.py +282 -0
  302. tnfr/utils/__init__.pyi +215 -0
  303. tnfr/utils/cache.py +4223 -0
  304. tnfr/utils/cache.pyi +470 -0
  305. tnfr/{callback_utils.py → utils/callbacks.py} +26 -39
  306. tnfr/utils/callbacks.pyi +49 -0
  307. tnfr/utils/chunks.py +108 -0
  308. tnfr/utils/chunks.pyi +22 -0
  309. tnfr/utils/data.py +428 -0
  310. tnfr/utils/data.pyi +74 -0
  311. tnfr/utils/graph.py +85 -0
  312. tnfr/utils/graph.pyi +10 -0
  313. tnfr/utils/init.py +821 -0
  314. tnfr/utils/init.pyi +80 -0
  315. tnfr/utils/io.py +559 -0
  316. tnfr/utils/io.pyi +66 -0
  317. tnfr/{helpers → utils}/numeric.py +51 -24
  318. tnfr/utils/numeric.pyi +21 -0
  319. tnfr/validation/__init__.py +257 -0
  320. tnfr/validation/__init__.pyi +85 -0
  321. tnfr/validation/compatibility.py +460 -0
  322. tnfr/validation/compatibility.pyi +6 -0
  323. tnfr/validation/config.py +73 -0
  324. tnfr/validation/graph.py +139 -0
  325. tnfr/validation/graph.pyi +18 -0
  326. tnfr/validation/input_validation.py +755 -0
  327. tnfr/validation/invariants.py +712 -0
  328. tnfr/validation/rules.py +253 -0
  329. tnfr/validation/rules.pyi +44 -0
  330. tnfr/validation/runtime.py +279 -0
  331. tnfr/validation/runtime.pyi +28 -0
  332. tnfr/validation/sequence_validator.py +162 -0
  333. tnfr/validation/soft_filters.py +170 -0
  334. tnfr/validation/soft_filters.pyi +32 -0
  335. tnfr/validation/spectral.py +164 -0
  336. tnfr/validation/spectral.pyi +42 -0
  337. tnfr/validation/validator.py +1266 -0
  338. tnfr/validation/window.py +39 -0
  339. tnfr/validation/window.pyi +1 -0
  340. tnfr/visualization/__init__.py +98 -0
  341. tnfr/visualization/cascade_viz.py +256 -0
  342. tnfr/visualization/hierarchy.py +284 -0
  343. tnfr/visualization/sequence_plotter.py +784 -0
  344. tnfr/viz/__init__.py +60 -0
  345. tnfr/viz/matplotlib.py +278 -0
  346. tnfr/viz/matplotlib.pyi +35 -0
  347. tnfr-8.5.0.dist-info/METADATA +573 -0
  348. tnfr-8.5.0.dist-info/RECORD +353 -0
  349. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/entry_points.txt +1 -0
  350. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/licenses/LICENSE.md +1 -1
  351. tnfr/collections_utils.py +0 -300
  352. tnfr/config.py +0 -32
  353. tnfr/grammar.py +0 -344
  354. tnfr/graph_utils.py +0 -84
  355. tnfr/helpers/__init__.py +0 -71
  356. tnfr/import_utils.py +0 -228
  357. tnfr/json_utils.py +0 -162
  358. tnfr/logging_utils.py +0 -116
  359. tnfr/presets.py +0 -60
  360. tnfr/validators.py +0 -84
  361. tnfr/value_utils.py +0 -59
  362. tnfr-4.5.2.dist-info/METADATA +0 -379
  363. tnfr-4.5.2.dist-info/RECORD +0 -67
  364. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
  365. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
tnfr/core/container.py ADDED
@@ -0,0 +1,226 @@
1
+ """Dependency injection container for TNFR engine components.
2
+
3
+ This module provides a lightweight dependency injection container that allows
4
+ configuring and resolving engine components (validators, registries, dynamics
5
+ engines, telemetry collectors) without hard-coding implementations.
6
+
7
+ The container supports both singleton and factory registrations, enabling
8
+ flexible composition of TNFR services while maintaining clean separation of
9
+ concerns.
10
+
11
+ Examples
12
+ --------
13
+ Create a container with default implementations:
14
+
15
+ >>> container = TNFRContainer.create_default()
16
+ >>> validator = container.get(ValidationService)
17
+ >>> validator.validate_sequence(["emission", "coherence"])
18
+
19
+ Register custom implementations:
20
+
21
+ >>> container = TNFRContainer()
22
+ >>> container.register_singleton(ValidationService, CustomValidator())
23
+ >>> validator = container.get(ValidationService)
24
+ """
25
+
26
+ from __future__ import annotations
27
+
28
+ from typing import Any, Callable, TypeVar
29
+
30
+ T = TypeVar("T")
31
+
32
+ __all__ = ("TNFRContainer",)
33
+
34
+
35
+ class TNFRContainer:
36
+ """Dependency injection container for TNFR engine components.
37
+
38
+ The container manages the lifecycle of engine services, allowing
39
+ registration of singletons (reused instances) or factories (fresh
40
+ instances on each request). This enables flexible configuration without
41
+ coupling client code to specific implementations.
42
+
43
+ Examples
44
+ --------
45
+ Basic usage with singleton registration:
46
+
47
+ >>> from tnfr.core.interfaces import ValidationService
48
+ >>> class MyValidator:
49
+ ... def validate_sequence(self, seq):
50
+ ... pass
51
+ ... def validate_graph_state(self, graph):
52
+ ... pass
53
+ >>> container = TNFRContainer()
54
+ >>> container.register_singleton(ValidationService, MyValidator())
55
+ >>> validator = container.get(ValidationService)
56
+
57
+ Factory registration for per-request instances:
58
+
59
+ >>> container.register_factory(ValidationService, MyValidator)
60
+ >>> v1 = container.get(ValidationService)
61
+ >>> v2 = container.get(ValidationService)
62
+ >>> v1 is not v2 # Different instances
63
+ True
64
+ """
65
+
66
+ def __init__(self) -> None:
67
+ """Initialize an empty container."""
68
+ self._instances: dict[Any, Any] = {}
69
+ self._factories: dict[Any, Callable[[], Any]] = {}
70
+ self._is_singleton: dict[Any, bool] = {} # Track singleton status
71
+
72
+ def register_singleton(self, interface: type[T], implementation: T) -> None:
73
+ """Register an implementation as a singleton.
74
+
75
+ The provided instance will be cached and returned for all subsequent
76
+ requests for this interface.
77
+
78
+ Parameters
79
+ ----------
80
+ interface : type
81
+ The interface or abstract type to register against.
82
+ implementation : T
83
+ The concrete instance to return for this interface.
84
+
85
+ Examples
86
+ --------
87
+ >>> container = TNFRContainer()
88
+ >>> container.register_singleton(ValidationService, MyValidator())
89
+ """
90
+ # Store as a factory that returns the same instance
91
+ self._factories[interface] = lambda: implementation
92
+ self._is_singleton[interface] = True
93
+
94
+ def register_factory(
95
+ self, interface: type[T], factory_func: Callable[[], T]
96
+ ) -> None:
97
+ """Register a factory function for creating instances.
98
+
99
+ The factory will be called each time the interface is requested,
100
+ allowing fresh instances or cached instances depending on the
101
+ factory implementation.
102
+
103
+ Parameters
104
+ ----------
105
+ interface : type
106
+ The interface or abstract type to register against.
107
+ factory_func : callable
108
+ Function that creates and returns an instance of the interface.
109
+
110
+ Examples
111
+ --------
112
+ >>> container = TNFRContainer()
113
+ >>> container.register_factory(ValidationService, MyValidator)
114
+ """
115
+ self._factories[interface] = factory_func
116
+ self._is_singleton[interface] = False
117
+
118
+ def get(self, interface: type[T]) -> T:
119
+ """Retrieve an instance implementing the specified interface.
120
+
121
+ For singleton registrations, returns the cached instance. For factory
122
+ registrations, calls the factory to produce an instance.
123
+
124
+ Parameters
125
+ ----------
126
+ interface : type
127
+ The interface type to resolve.
128
+
129
+ Returns
130
+ -------
131
+ T
132
+ Instance implementing the interface.
133
+
134
+ Raises
135
+ ------
136
+ ValueError
137
+ When no factory is registered for the interface.
138
+
139
+ Examples
140
+ --------
141
+ >>> container = TNFRContainer()
142
+ >>> container.register_singleton(ValidationService, MyValidator())
143
+ >>> validator = container.get(ValidationService)
144
+ """
145
+ # Check if we have a cached singleton instance
146
+ if interface in self._instances:
147
+ return self._instances[interface]
148
+
149
+ # Check if we have a factory registered
150
+ if interface not in self._factories:
151
+ raise ValueError(
152
+ f"No factory registered for {interface}. "
153
+ f"Use register_singleton() or register_factory() first."
154
+ )
155
+
156
+ # Call factory
157
+ instance = self._factories[interface]()
158
+
159
+ # Cache only if registered as singleton
160
+ if self._is_singleton.get(interface, False):
161
+ self._instances[interface] = instance
162
+
163
+ return instance
164
+
165
+ def has(self, interface: type) -> bool:
166
+ """Check if an interface has a registered factory.
167
+
168
+ Parameters
169
+ ----------
170
+ interface : type
171
+ The interface type to check.
172
+
173
+ Returns
174
+ -------
175
+ bool
176
+ True if a factory is registered for this interface.
177
+ """
178
+ return interface in self._factories
179
+
180
+ @classmethod
181
+ def create_default(cls) -> TNFRContainer:
182
+ """Create a container with default TNFR implementations.
183
+
184
+ This factory method registers the standard implementations of all
185
+ core interfaces, making it easy to get started with the TNFR engine
186
+ without manual configuration.
187
+
188
+ Returns
189
+ -------
190
+ TNFRContainer
191
+ Container configured with default implementations.
192
+
193
+ Examples
194
+ --------
195
+ >>> container = TNFRContainer.create_default()
196
+ >>> validator = container.get(ValidationService)
197
+ >>> # Use validator with default implementation
198
+
199
+ Notes
200
+ -----
201
+ The default implementations are imported lazily to avoid circular
202
+ dependencies. Custom implementations can be registered after creation
203
+ to override defaults.
204
+ """
205
+ from .default_implementations import (
206
+ DefaultDynamicsEngine,
207
+ DefaultOperatorRegistry,
208
+ DefaultTelemetryCollector,
209
+ DefaultValidationService,
210
+ )
211
+ from .interfaces import (
212
+ DynamicsEngine,
213
+ OperatorRegistry,
214
+ TelemetryCollector,
215
+ ValidationService,
216
+ )
217
+
218
+ container = cls()
219
+
220
+ # Register default implementations as singletons
221
+ container.register_singleton(ValidationService, DefaultValidationService())
222
+ container.register_singleton(OperatorRegistry, DefaultOperatorRegistry())
223
+ container.register_singleton(DynamicsEngine, DefaultDynamicsEngine())
224
+ container.register_singleton(TelemetryCollector, DefaultTelemetryCollector())
225
+
226
+ return container
@@ -0,0 +1,329 @@
1
+ """Default implementations of TNFR core interfaces.
2
+
3
+ This module provides concrete implementations of the architectural interfaces
4
+ that wrap existing TNFR functionality. These implementations maintain backward
5
+ compatibility while enabling the new modular architecture.
6
+
7
+ Classes
8
+ -------
9
+ DefaultValidationService
10
+ Wraps tnfr.validation for sequence and graph validation.
11
+ DefaultOperatorRegistry
12
+ Wraps tnfr.operators.registry for operator management.
13
+ DefaultDynamicsEngine
14
+ Wraps tnfr.dynamics for ΔNFR computation and integration.
15
+ DefaultTelemetryCollector
16
+ Wraps tnfr.metrics for coherence and sense index computation.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from contextlib import contextmanager
22
+ from typing import TYPE_CHECKING, Any
23
+
24
+ if TYPE_CHECKING:
25
+ from ..types import TNFRGraph
26
+ from ..operators.definitions import Operator
27
+
28
+ __all__ = (
29
+ "DefaultValidationService",
30
+ "DefaultOperatorRegistry",
31
+ "DefaultDynamicsEngine",
32
+ "DefaultTelemetryCollector",
33
+ )
34
+
35
+
36
+ class DefaultValidationService:
37
+ """Default implementation of ValidationService using tnfr.validation.
38
+
39
+ This implementation wraps the existing validation infrastructure to
40
+ provide the ValidationService interface without modifying existing code.
41
+ """
42
+
43
+ def validate_sequence(self, sequence: list[str]) -> None:
44
+ """Validate operator sequence using canonical grammar rules.
45
+
46
+ Parameters
47
+ ----------
48
+ sequence : list of str
49
+ Operator tokens to validate.
50
+
51
+ Raises
52
+ ------
53
+ ValueError
54
+ When sequence violates TNFR grammar or operator closure.
55
+ """
56
+ from ..validation import validate_sequence as _validate_sequence
57
+
58
+ # validate_sequence returns ValidationOutcome
59
+ outcome = _validate_sequence(sequence)
60
+ if not outcome.passed:
61
+ summary_message = outcome.summary.get("message", "validation failed")
62
+ raise ValueError(f"Invalid sequence: {summary_message}")
63
+
64
+ def validate_graph_state(self, graph: TNFRGraph) -> None:
65
+ """Validate graph state using canonical validators.
66
+
67
+ Parameters
68
+ ----------
69
+ graph : TNFRGraph
70
+ Graph to validate.
71
+
72
+ Raises
73
+ ------
74
+ ValueError
75
+ When graph state violates structural invariants.
76
+ """
77
+ from ..validation import run_validators
78
+
79
+ # run_validators raises on failure by default
80
+ run_validators(graph)
81
+
82
+
83
+ class DefaultOperatorRegistry:
84
+ """Default implementation of OperatorRegistry using tnfr.operators.
85
+
86
+ This implementation wraps the global OPERATORS registry to provide
87
+ the OperatorRegistry interface.
88
+ """
89
+
90
+ def get_operator(self, token: str) -> Operator:
91
+ """Retrieve operator by token from global registry.
92
+
93
+ Parameters
94
+ ----------
95
+ token : str
96
+ Operator identifier.
97
+
98
+ Returns
99
+ -------
100
+ Operator
101
+ The structural operator implementation (class, not instance).
102
+
103
+ Raises
104
+ ------
105
+ KeyError
106
+ When token is not registered.
107
+ """
108
+ from ..operators.registry import get_operator_class
109
+
110
+ # get_operator_class returns the operator class
111
+ return get_operator_class(token)
112
+
113
+ def register_operator(self, operator: Operator) -> None:
114
+ """Register operator in global registry.
115
+
116
+ Parameters
117
+ ----------
118
+ operator : Operator
119
+ Operator to register.
120
+ """
121
+ from ..operators.registry import OPERATORS
122
+
123
+ # Register by operator name
124
+ OPERATORS[operator.name] = operator.__class__
125
+
126
+
127
+ class DefaultDynamicsEngine:
128
+ """Default implementation of DynamicsEngine using tnfr.dynamics.
129
+
130
+ This implementation wraps existing dynamics functions to provide
131
+ the DynamicsEngine interface.
132
+ """
133
+
134
+ def update_delta_nfr(self, graph: TNFRGraph) -> None:
135
+ """Compute ΔNFR using configured hook.
136
+
137
+ Parameters
138
+ ----------
139
+ graph : TNFRGraph
140
+ Graph to update.
141
+ """
142
+ # Get the configured ΔNFR hook from graph metadata
143
+ compute = graph.graph.get("compute_delta_nfr")
144
+ if callable(compute):
145
+ compute(graph)
146
+
147
+ def integrate_nodal_equation(self, graph: TNFRGraph) -> None:
148
+ """Integrate nodal equation to update EPI.
149
+
150
+ Parameters
151
+ ----------
152
+ graph : TNFRGraph
153
+ Graph to integrate.
154
+ """
155
+ from ..dynamics.integrators import update_epi_via_nodal_equation
156
+
157
+ # Use default integration parameters from graph
158
+ dt = graph.graph.get("dt", 0.1)
159
+ update_epi_via_nodal_equation(graph, dt=dt)
160
+
161
+ def coordinate_phase_coupling(self, graph: TNFRGraph) -> None:
162
+ """Coordinate phase synchronization.
163
+
164
+ Parameters
165
+ ----------
166
+ graph : TNFRGraph
167
+ Graph whose phase is coordinated.
168
+ """
169
+ from ..dynamics.coordination import coordinate_global_local_phase
170
+
171
+ # Coordinate phase using default parameters
172
+ coordinate_global_local_phase(graph)
173
+
174
+
175
+ class DefaultTraceContext:
176
+ """Default trace context for telemetry collection.
177
+
178
+ This context manager captures graph state before and after operator
179
+ application, recording transitions for structural analysis.
180
+ """
181
+
182
+ def __init__(self, graph: TNFRGraph):
183
+ """Initialize trace context.
184
+
185
+ Parameters
186
+ ----------
187
+ graph : TNFRGraph
188
+ Graph being traced.
189
+ """
190
+ self.graph = graph
191
+ self.transitions: list[dict[str, Any]] = []
192
+
193
+ def __enter__(self):
194
+ """Enter trace context."""
195
+ return self
196
+
197
+ def __exit__(self, exc_type, exc_val, exc_tb):
198
+ """Exit trace context."""
199
+ # Save transitions when exiting context
200
+ self._save_transitions()
201
+ return False
202
+
203
+ def _save_transitions(self) -> None:
204
+ """Save transitions to graph metadata."""
205
+ if self.transitions:
206
+ existing = self.graph.graph.get("_trace_transitions", [])
207
+ existing_copy = list(existing) # Make a copy to avoid mutation
208
+ existing_copy.extend(self.transitions)
209
+ self.graph.graph["_trace_transitions"] = existing_copy
210
+
211
+ def capture_state(self, graph: TNFRGraph) -> dict[str, Any]:
212
+ """Capture current graph state.
213
+
214
+ Parameters
215
+ ----------
216
+ graph : TNFRGraph
217
+ Graph to capture.
218
+
219
+ Returns
220
+ -------
221
+ dict
222
+ State snapshot.
223
+ """
224
+ from ..metrics.common import compute_coherence
225
+
226
+ # Capture key metrics
227
+ return {
228
+ "coherence": compute_coherence(graph),
229
+ "node_count": graph.number_of_nodes(),
230
+ "edge_count": (
231
+ graph.number_of_edges() if hasattr(graph, "number_of_edges") else 0
232
+ ),
233
+ }
234
+
235
+ def record_transition(
236
+ self,
237
+ operator_token: str,
238
+ pre_state: dict[str, Any],
239
+ post_state: dict[str, Any],
240
+ ) -> None:
241
+ """Record operator transition.
242
+
243
+ Parameters
244
+ ----------
245
+ operator_token : str
246
+ Operator that caused transition.
247
+ pre_state : dict
248
+ State before operator.
249
+ post_state : dict
250
+ State after operator.
251
+ """
252
+ self.transitions.append(
253
+ {
254
+ "operator": operator_token,
255
+ "pre": pre_state,
256
+ "post": post_state,
257
+ "delta_coherence": post_state["coherence"] - pre_state["coherence"],
258
+ }
259
+ )
260
+
261
+
262
+ class DefaultTelemetryCollector:
263
+ """Default implementation of TelemetryCollector using tnfr.metrics.
264
+
265
+ This implementation wraps existing metrics functions to provide
266
+ the TelemetryCollector interface.
267
+ """
268
+
269
+ @contextmanager
270
+ def trace_context(self, graph: TNFRGraph):
271
+ """Create trace context for operator execution.
272
+
273
+ Parameters
274
+ ----------
275
+ graph : TNFRGraph
276
+ Graph being traced.
277
+
278
+ Yields
279
+ ------
280
+ DefaultTraceContext
281
+ Context for capturing transitions.
282
+ """
283
+ context = DefaultTraceContext(graph)
284
+ try:
285
+ yield context
286
+ finally:
287
+ # Ensure transitions are saved using the helper method
288
+ context._save_transitions()
289
+
290
+ def compute_coherence(self, graph: TNFRGraph) -> float:
291
+ """Compute global coherence C(t).
292
+
293
+ Parameters
294
+ ----------
295
+ graph : TNFRGraph
296
+ Graph to measure.
297
+
298
+ Returns
299
+ -------
300
+ float
301
+ Coherence value in [0, 1].
302
+ """
303
+ from ..metrics.common import compute_coherence
304
+
305
+ return compute_coherence(graph)
306
+
307
+ def compute_sense_index(self, graph: TNFRGraph) -> dict[str, Any]:
308
+ """Compute sense index Si.
309
+
310
+ Parameters
311
+ ----------
312
+ graph : TNFRGraph
313
+ Graph to measure.
314
+
315
+ Returns
316
+ -------
317
+ dict
318
+ Sense index metrics.
319
+ """
320
+ from ..metrics.sense_index import compute_Si
321
+
322
+ result = compute_Si(graph)
323
+
324
+ # Ensure we return a dict
325
+ if isinstance(result, dict):
326
+ return result
327
+ else:
328
+ # If compute_Si returns a scalar, wrap it
329
+ return {"Si": result}