tnfr 3.0.3__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 (360) hide show
  1. tnfr/__init__.py +375 -56
  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 +723 -0
  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 +171 -0
  15. tnfr/cache.pyi +13 -0
  16. tnfr/cli/__init__.py +110 -0
  17. tnfr/cli/__init__.pyi +26 -0
  18. tnfr/cli/arguments.py +489 -0
  19. tnfr/cli/arguments.pyi +29 -0
  20. tnfr/cli/execution.py +914 -0
  21. tnfr/cli/execution.pyi +70 -0
  22. tnfr/cli/interactive_validator.py +614 -0
  23. tnfr/cli/utils.py +51 -0
  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/config/constants.py +104 -0
  34. tnfr/config/constants.pyi +12 -0
  35. tnfr/config/defaults.py +54 -0
  36. tnfr/config/defaults_core.py +212 -0
  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 +92 -0
  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 +33 -0
  57. tnfr/constants/init.pyi +12 -0
  58. tnfr/constants/metric.py +104 -0
  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 +238 -0
  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 +3034 -0
  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 +661 -0
  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 +36 -0
  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 +223 -0
  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 +262 -0
  125. tnfr/flatten.pyi +21 -0
  126. tnfr/gamma.py +354 -0
  127. tnfr/gamma.pyi +36 -0
  128. tnfr/glyph_history.py +377 -0
  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 +218 -0
  133. tnfr/immutable.pyi +36 -0
  134. tnfr/initialization.py +203 -0
  135. tnfr/initialization.pyi +65 -0
  136. tnfr/io.py +10 -0
  137. tnfr/io.pyi +13 -0
  138. tnfr/locking.py +37 -0
  139. tnfr/locking.pyi +7 -0
  140. tnfr/mathematics/__init__.py +79 -0
  141. tnfr/mathematics/backend.py +453 -0
  142. tnfr/mathematics/backend.pyi +99 -0
  143. tnfr/mathematics/dynamics.py +408 -0
  144. tnfr/mathematics/dynamics.pyi +90 -0
  145. tnfr/mathematics/epi.py +391 -0
  146. tnfr/mathematics/epi.pyi +65 -0
  147. tnfr/mathematics/generators.py +242 -0
  148. tnfr/mathematics/generators.pyi +29 -0
  149. tnfr/mathematics/metrics.py +119 -0
  150. tnfr/mathematics/metrics.pyi +16 -0
  151. tnfr/mathematics/operators.py +239 -0
  152. tnfr/mathematics/operators.pyi +59 -0
  153. tnfr/mathematics/operators_factory.py +124 -0
  154. tnfr/mathematics/operators_factory.pyi +11 -0
  155. tnfr/mathematics/projection.py +87 -0
  156. tnfr/mathematics/projection.pyi +33 -0
  157. tnfr/mathematics/runtime.py +182 -0
  158. tnfr/mathematics/runtime.pyi +64 -0
  159. tnfr/mathematics/spaces.py +256 -0
  160. tnfr/mathematics/spaces.pyi +83 -0
  161. tnfr/mathematics/transforms.py +305 -0
  162. tnfr/mathematics/transforms.pyi +62 -0
  163. tnfr/metrics/__init__.py +79 -0
  164. tnfr/metrics/__init__.pyi +20 -0
  165. tnfr/metrics/buffer_cache.py +163 -0
  166. tnfr/metrics/buffer_cache.pyi +24 -0
  167. tnfr/metrics/cache_utils.py +214 -0
  168. tnfr/metrics/coherence.py +2009 -0
  169. tnfr/metrics/coherence.pyi +129 -0
  170. tnfr/metrics/common.py +158 -0
  171. tnfr/metrics/common.pyi +35 -0
  172. tnfr/metrics/core.py +316 -0
  173. tnfr/metrics/core.pyi +13 -0
  174. tnfr/metrics/diagnosis.py +833 -0
  175. tnfr/metrics/diagnosis.pyi +86 -0
  176. tnfr/metrics/emergence.py +245 -0
  177. tnfr/metrics/export.py +179 -0
  178. tnfr/metrics/export.pyi +7 -0
  179. tnfr/metrics/glyph_timing.py +379 -0
  180. tnfr/metrics/glyph_timing.pyi +81 -0
  181. tnfr/metrics/learning_metrics.py +280 -0
  182. tnfr/metrics/learning_metrics.pyi +21 -0
  183. tnfr/metrics/phase_coherence.py +351 -0
  184. tnfr/metrics/phase_compatibility.py +349 -0
  185. tnfr/metrics/reporting.py +183 -0
  186. tnfr/metrics/reporting.pyi +25 -0
  187. tnfr/metrics/sense_index.py +1203 -0
  188. tnfr/metrics/sense_index.pyi +9 -0
  189. tnfr/metrics/trig.py +373 -0
  190. tnfr/metrics/trig.pyi +13 -0
  191. tnfr/metrics/trig_cache.py +233 -0
  192. tnfr/metrics/trig_cache.pyi +10 -0
  193. tnfr/multiscale/__init__.py +32 -0
  194. tnfr/multiscale/hierarchical.py +517 -0
  195. tnfr/node.py +763 -0
  196. tnfr/node.pyi +139 -0
  197. tnfr/observers.py +255 -130
  198. tnfr/observers.pyi +31 -0
  199. tnfr/ontosim.py +144 -137
  200. tnfr/ontosim.pyi +28 -0
  201. tnfr/operators/__init__.py +1672 -0
  202. tnfr/operators/__init__.pyi +31 -0
  203. tnfr/operators/algebra.py +277 -0
  204. tnfr/operators/canonical_patterns.py +420 -0
  205. tnfr/operators/cascade.py +267 -0
  206. tnfr/operators/cycle_detection.py +358 -0
  207. tnfr/operators/definitions.py +4108 -0
  208. tnfr/operators/definitions.pyi +78 -0
  209. tnfr/operators/grammar.py +1164 -0
  210. tnfr/operators/grammar.pyi +140 -0
  211. tnfr/operators/hamiltonian.py +710 -0
  212. tnfr/operators/health_analyzer.py +809 -0
  213. tnfr/operators/jitter.py +272 -0
  214. tnfr/operators/jitter.pyi +11 -0
  215. tnfr/operators/lifecycle.py +314 -0
  216. tnfr/operators/metabolism.py +618 -0
  217. tnfr/operators/metrics.py +2138 -0
  218. tnfr/operators/network_analysis/__init__.py +27 -0
  219. tnfr/operators/network_analysis/source_detection.py +186 -0
  220. tnfr/operators/nodal_equation.py +395 -0
  221. tnfr/operators/pattern_detection.py +660 -0
  222. tnfr/operators/patterns.py +669 -0
  223. tnfr/operators/postconditions/__init__.py +38 -0
  224. tnfr/operators/postconditions/mutation.py +236 -0
  225. tnfr/operators/preconditions/__init__.py +1226 -0
  226. tnfr/operators/preconditions/coherence.py +305 -0
  227. tnfr/operators/preconditions/dissonance.py +236 -0
  228. tnfr/operators/preconditions/emission.py +128 -0
  229. tnfr/operators/preconditions/mutation.py +580 -0
  230. tnfr/operators/preconditions/reception.py +125 -0
  231. tnfr/operators/preconditions/resonance.py +364 -0
  232. tnfr/operators/registry.py +74 -0
  233. tnfr/operators/registry.pyi +9 -0
  234. tnfr/operators/remesh.py +1809 -0
  235. tnfr/operators/remesh.pyi +26 -0
  236. tnfr/operators/structural_units.py +268 -0
  237. tnfr/operators/unified_grammar.py +105 -0
  238. tnfr/parallel/__init__.py +54 -0
  239. tnfr/parallel/auto_scaler.py +234 -0
  240. tnfr/parallel/distributed.py +384 -0
  241. tnfr/parallel/engine.py +238 -0
  242. tnfr/parallel/gpu_engine.py +420 -0
  243. tnfr/parallel/monitoring.py +248 -0
  244. tnfr/parallel/partitioner.py +459 -0
  245. tnfr/py.typed +0 -0
  246. tnfr/recipes/__init__.py +22 -0
  247. tnfr/recipes/cookbook.py +743 -0
  248. tnfr/rng.py +178 -0
  249. tnfr/rng.pyi +26 -0
  250. tnfr/schemas/__init__.py +8 -0
  251. tnfr/schemas/grammar.json +94 -0
  252. tnfr/sdk/__init__.py +107 -0
  253. tnfr/sdk/__init__.pyi +19 -0
  254. tnfr/sdk/adaptive_system.py +173 -0
  255. tnfr/sdk/adaptive_system.pyi +21 -0
  256. tnfr/sdk/builders.py +370 -0
  257. tnfr/sdk/builders.pyi +51 -0
  258. tnfr/sdk/fluent.py +1121 -0
  259. tnfr/sdk/fluent.pyi +74 -0
  260. tnfr/sdk/templates.py +342 -0
  261. tnfr/sdk/templates.pyi +41 -0
  262. tnfr/sdk/utils.py +341 -0
  263. tnfr/secure_config.py +46 -0
  264. tnfr/security/__init__.py +70 -0
  265. tnfr/security/database.py +514 -0
  266. tnfr/security/subprocess.py +503 -0
  267. tnfr/security/validation.py +290 -0
  268. tnfr/selector.py +247 -0
  269. tnfr/selector.pyi +19 -0
  270. tnfr/sense.py +378 -0
  271. tnfr/sense.pyi +23 -0
  272. tnfr/services/__init__.py +17 -0
  273. tnfr/services/orchestrator.py +325 -0
  274. tnfr/sparse/__init__.py +39 -0
  275. tnfr/sparse/representations.py +492 -0
  276. tnfr/structural.py +705 -0
  277. tnfr/structural.pyi +83 -0
  278. tnfr/telemetry/__init__.py +35 -0
  279. tnfr/telemetry/cache_metrics.py +226 -0
  280. tnfr/telemetry/cache_metrics.pyi +64 -0
  281. tnfr/telemetry/nu_f.py +422 -0
  282. tnfr/telemetry/nu_f.pyi +108 -0
  283. tnfr/telemetry/verbosity.py +36 -0
  284. tnfr/telemetry/verbosity.pyi +15 -0
  285. tnfr/tokens.py +58 -0
  286. tnfr/tokens.pyi +36 -0
  287. tnfr/tools/__init__.py +20 -0
  288. tnfr/tools/domain_templates.py +478 -0
  289. tnfr/tools/sequence_generator.py +846 -0
  290. tnfr/topology/__init__.py +13 -0
  291. tnfr/topology/asymmetry.py +151 -0
  292. tnfr/trace.py +543 -0
  293. tnfr/trace.pyi +42 -0
  294. tnfr/tutorials/__init__.py +38 -0
  295. tnfr/tutorials/autonomous_evolution.py +285 -0
  296. tnfr/tutorials/interactive.py +1576 -0
  297. tnfr/tutorials/structural_metabolism.py +238 -0
  298. tnfr/types.py +775 -0
  299. tnfr/types.pyi +357 -0
  300. tnfr/units.py +68 -0
  301. tnfr/units.pyi +13 -0
  302. tnfr/utils/__init__.py +282 -0
  303. tnfr/utils/__init__.pyi +215 -0
  304. tnfr/utils/cache.py +4223 -0
  305. tnfr/utils/cache.pyi +470 -0
  306. tnfr/utils/callbacks.py +375 -0
  307. tnfr/utils/callbacks.pyi +49 -0
  308. tnfr/utils/chunks.py +108 -0
  309. tnfr/utils/chunks.pyi +22 -0
  310. tnfr/utils/data.py +428 -0
  311. tnfr/utils/data.pyi +74 -0
  312. tnfr/utils/graph.py +85 -0
  313. tnfr/utils/graph.pyi +10 -0
  314. tnfr/utils/init.py +821 -0
  315. tnfr/utils/init.pyi +80 -0
  316. tnfr/utils/io.py +559 -0
  317. tnfr/utils/io.pyi +66 -0
  318. tnfr/utils/numeric.py +114 -0
  319. tnfr/utils/numeric.pyi +21 -0
  320. tnfr/validation/__init__.py +257 -0
  321. tnfr/validation/__init__.pyi +85 -0
  322. tnfr/validation/compatibility.py +460 -0
  323. tnfr/validation/compatibility.pyi +6 -0
  324. tnfr/validation/config.py +73 -0
  325. tnfr/validation/graph.py +139 -0
  326. tnfr/validation/graph.pyi +18 -0
  327. tnfr/validation/input_validation.py +755 -0
  328. tnfr/validation/invariants.py +712 -0
  329. tnfr/validation/rules.py +253 -0
  330. tnfr/validation/rules.pyi +44 -0
  331. tnfr/validation/runtime.py +279 -0
  332. tnfr/validation/runtime.pyi +28 -0
  333. tnfr/validation/sequence_validator.py +162 -0
  334. tnfr/validation/soft_filters.py +170 -0
  335. tnfr/validation/soft_filters.pyi +32 -0
  336. tnfr/validation/spectral.py +164 -0
  337. tnfr/validation/spectral.pyi +42 -0
  338. tnfr/validation/validator.py +1266 -0
  339. tnfr/validation/window.py +39 -0
  340. tnfr/validation/window.pyi +1 -0
  341. tnfr/visualization/__init__.py +98 -0
  342. tnfr/visualization/cascade_viz.py +256 -0
  343. tnfr/visualization/hierarchy.py +284 -0
  344. tnfr/visualization/sequence_plotter.py +784 -0
  345. tnfr/viz/__init__.py +60 -0
  346. tnfr/viz/matplotlib.py +278 -0
  347. tnfr/viz/matplotlib.pyi +35 -0
  348. tnfr-8.5.0.dist-info/METADATA +573 -0
  349. tnfr-8.5.0.dist-info/RECORD +353 -0
  350. tnfr-8.5.0.dist-info/entry_points.txt +3 -0
  351. tnfr-3.0.3.dist-info/licenses/LICENSE.txt → tnfr-8.5.0.dist-info/licenses/LICENSE.md +1 -1
  352. tnfr/constants.py +0 -183
  353. tnfr/dynamics.py +0 -543
  354. tnfr/helpers.py +0 -198
  355. tnfr/main.py +0 -37
  356. tnfr/operators.py +0 -296
  357. tnfr-3.0.3.dist-info/METADATA +0 -35
  358. tnfr-3.0.3.dist-info/RECORD +0 -13
  359. {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
  360. {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
tnfr/rng.py ADDED
@@ -0,0 +1,178 @@
1
+ """Deterministic RNG helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import random
7
+ import struct
8
+ from typing import Any, cast
9
+
10
+ from cachetools import cached # type: ignore[import-untyped]
11
+
12
+ from .constants import DEFAULTS, get_param
13
+ from .locking import get_lock
14
+ from .types import GraphLike, TNFRGraph
15
+ from .utils import (
16
+ ScopedCounterCache,
17
+ _SeedHashCache,
18
+ build_cache_manager,
19
+ get_graph,
20
+ )
21
+
22
+ MASK64 = 0xFFFFFFFFFFFFFFFF
23
+
24
+ _RNG_LOCK = get_lock("rng")
25
+ _DEFAULT_CACHE_MAXSIZE = int(DEFAULTS.get("JITTER_CACHE_SIZE", 128))
26
+ _CACHE_MAXSIZE = _DEFAULT_CACHE_MAXSIZE
27
+ _CACHE_LOCKED = False
28
+
29
+ _RNG_CACHE_MANAGER = build_cache_manager(default_capacity=_DEFAULT_CACHE_MAXSIZE)
30
+
31
+ _seed_hash_cache = _SeedHashCache(
32
+ manager=_RNG_CACHE_MANAGER,
33
+ default_maxsize=_DEFAULT_CACHE_MAXSIZE,
34
+ )
35
+
36
+
37
+ def _compute_seed_hash(seed_int: int, key_int: int) -> int:
38
+ seed_bytes = struct.pack(
39
+ ">QQ",
40
+ seed_int & MASK64,
41
+ key_int & MASK64,
42
+ )
43
+ return int.from_bytes(hashlib.blake2b(seed_bytes, digest_size=8).digest(), "big")
44
+
45
+
46
+ @cached(cache=_seed_hash_cache, lock=_RNG_LOCK)
47
+ def _cached_seed_hash(seed_int: int, key_int: int) -> int:
48
+ return _compute_seed_hash(seed_int, key_int)
49
+
50
+
51
+ def seed_hash(seed_int: int, key_int: int) -> int:
52
+ """Return a 64-bit hash derived from ``seed_int`` and ``key_int``."""
53
+
54
+ if _CACHE_MAXSIZE <= 0 or not _seed_hash_cache.enabled:
55
+ return _compute_seed_hash(seed_int, key_int)
56
+ return _cached_seed_hash(seed_int, key_int)
57
+
58
+
59
+ seed_hash.cache_clear = cast(Any, _cached_seed_hash).cache_clear # type: ignore[attr-defined]
60
+ seed_hash.cache = _seed_hash_cache # type: ignore[attr-defined]
61
+
62
+
63
+ def _sync_cache_size(G: TNFRGraph | GraphLike | None) -> None:
64
+ """Synchronise cache size with ``G`` when needed."""
65
+
66
+ global _CACHE_MAXSIZE
67
+ if G is None or _CACHE_LOCKED:
68
+ return
69
+ size = get_cache_maxsize(G)
70
+ with _RNG_LOCK:
71
+ if size != _seed_hash_cache.maxsize:
72
+ _seed_hash_cache.configure(size)
73
+ _CACHE_MAXSIZE = _seed_hash_cache.maxsize
74
+
75
+
76
+ def make_rng(
77
+ seed: int, key: int, G: TNFRGraph | GraphLike | None = None
78
+ ) -> random.Random:
79
+ """Create a reproducible RNG instance from seed and key.
80
+
81
+ This factory constructs a deterministic :class:`random.Random` generator
82
+ by hashing the seed and key together. The hash result is cached for
83
+ performance when the same (seed, key) pair is requested repeatedly.
84
+
85
+ Parameters
86
+ ----------
87
+ seed : int
88
+ Base random seed for the generator. Must be an integer.
89
+ key : int
90
+ Key used to derive a unique hash with the seed. Multiple keys
91
+ allow independent RNG streams from the same base seed.
92
+ G : TNFRGraph | GraphLike | None, optional
93
+ Graph containing JITTER_CACHE_SIZE parameter. When provided, the
94
+ internal cache size is synchronized with the graph configuration.
95
+
96
+ Returns
97
+ -------
98
+ random.Random
99
+ Deterministic random number generator seeded with hash(seed, key).
100
+
101
+ Notes
102
+ -----
103
+ The same (seed, key) pair always produces the same generator state,
104
+ ensuring reproducibility across TNFR simulations. Cache synchronization
105
+ with ``G`` allows adaptive caching based on simulation requirements.
106
+ """
107
+ _sync_cache_size(G)
108
+ seed_int = int(seed)
109
+ key_int = int(key)
110
+ return random.Random(seed_hash(seed_int, key_int))
111
+
112
+
113
+ def clear_rng_cache() -> None:
114
+ """Clear cached seed hashes."""
115
+ if _seed_hash_cache.maxsize <= 0 or not _seed_hash_cache.enabled:
116
+ return
117
+ seed_hash.cache_clear() # type: ignore[attr-defined]
118
+
119
+
120
+ def get_cache_maxsize(G: TNFRGraph | GraphLike) -> int:
121
+ """Return RNG cache maximum size for ``G``."""
122
+ return int(get_param(G, "JITTER_CACHE_SIZE"))
123
+
124
+
125
+ def cache_enabled(G: TNFRGraph | GraphLike | None = None) -> bool:
126
+ """Return ``True`` if RNG caching is enabled.
127
+
128
+ When ``G`` is provided, the cache size is synchronised with
129
+ ``JITTER_CACHE_SIZE`` stored in ``G``.
130
+ """
131
+ # Only synchronise the cache size with ``G`` when caching is enabled. This
132
+ # preserves explicit calls to :func:`set_cache_maxsize(0)` which are used in
133
+ # tests to temporarily disable caching regardless of graph defaults.
134
+ if _seed_hash_cache.maxsize > 0:
135
+ _sync_cache_size(G)
136
+ return _seed_hash_cache.maxsize > 0
137
+
138
+
139
+ def base_seed(G: TNFRGraph | GraphLike) -> int:
140
+ """Return base RNG seed stored in ``G.graph``."""
141
+ graph = get_graph(G)
142
+ return int(graph.get("RANDOM_SEED", 0))
143
+
144
+
145
+ def _rng_for_step(seed: int, step: int) -> random.Random:
146
+ """Return deterministic RNG for a simulation ``step``."""
147
+
148
+ return make_rng(seed, step)
149
+
150
+
151
+ def set_cache_maxsize(size: int) -> None:
152
+ """Update RNG cache maximum size.
153
+
154
+ ``size`` must be a non-negative integer; ``0`` disables caching.
155
+ Changing the cache size resets any cached seed hashes.
156
+ If caching is disabled, ``clear_rng_cache`` has no effect.
157
+ """
158
+
159
+ global _CACHE_MAXSIZE, _CACHE_LOCKED
160
+ new_size = int(size)
161
+ if new_size < 0:
162
+ raise ValueError("size must be non-negative")
163
+ with _RNG_LOCK:
164
+ _seed_hash_cache.configure(new_size)
165
+ _CACHE_MAXSIZE = _seed_hash_cache.maxsize
166
+ _CACHE_LOCKED = new_size != _DEFAULT_CACHE_MAXSIZE
167
+
168
+
169
+ __all__ = (
170
+ "seed_hash",
171
+ "make_rng",
172
+ "get_cache_maxsize",
173
+ "set_cache_maxsize",
174
+ "base_seed",
175
+ "cache_enabled",
176
+ "clear_rng_cache",
177
+ "ScopedCounterCache",
178
+ )
tnfr/rng.pyi ADDED
@@ -0,0 +1,26 @@
1
+ from __future__ import annotations
2
+
3
+ import random
4
+ from .types import GraphLike, TNFRGraph
5
+ from .utils import ScopedCounterCache as ScopedCounterCache
6
+
7
+ __all__ = [
8
+ "seed_hash",
9
+ "make_rng",
10
+ "get_cache_maxsize",
11
+ "set_cache_maxsize",
12
+ "base_seed",
13
+ "cache_enabled",
14
+ "clear_rng_cache",
15
+ "ScopedCounterCache",
16
+ ]
17
+
18
+ def seed_hash(seed_int: int, key_int: int) -> int: ...
19
+ def make_rng(
20
+ seed: int, key: int, G: TNFRGraph | GraphLike | None = None
21
+ ) -> random.Random: ...
22
+ def clear_rng_cache() -> None: ...
23
+ def get_cache_maxsize(G: TNFRGraph | GraphLike) -> int: ...
24
+ def cache_enabled(G: TNFRGraph | GraphLike | None = None) -> bool: ...
25
+ def base_seed(G: TNFRGraph | GraphLike) -> int: ...
26
+ def set_cache_maxsize(size: int) -> None: ...
@@ -0,0 +1,8 @@
1
+ """JSON schema resources bundled with the TNFR engine."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __all__ = ["package"]
6
+
7
+ # Namespace packages need at least one attribute for static analysers.
8
+ package = __name__
@@ -0,0 +1,94 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://tnfr.io/schemas/grammar.json",
4
+ "title": "TNFR Grammar Configuration",
5
+ "type": "object",
6
+ "definitions": {
7
+ "glyphCode": {
8
+ "description": "Canonical glyph identifier in uppercase notation.",
9
+ "type": "string",
10
+ "pattern": "^[A-Z][A-Z_]*$"
11
+ },
12
+ "probability": {
13
+ "description": "Threshold constrained to the [0, 1] interval.",
14
+ "type": "number",
15
+ "minimum": 0.0,
16
+ "maximum": 1.0
17
+ },
18
+ "cfg_soft": {
19
+ "type": "object",
20
+ "description": "Soft grammar preferences applied before canonical automaton rules.",
21
+ "properties": {
22
+ "window": {
23
+ "description": "History window inspected to avoid short-term glyph repetitions.",
24
+ "type": "integer",
25
+ "minimum": 0
26
+ },
27
+ "avoid_repeats": {
28
+ "description": "Glyph codes that should be substituted when repeated inside the window.",
29
+ "type": "array",
30
+ "items": { "$ref": "#/definitions/glyphCode" },
31
+ "uniqueItems": true
32
+ },
33
+ "fallbacks": {
34
+ "description": "Mapping of glyph codes to their explicit substitution when repetition is detected.",
35
+ "type": "object",
36
+ "additionalProperties": { "$ref": "#/definitions/glyphCode" }
37
+ },
38
+ "force_dnfr": {
39
+ "description": "Minimum |ΔNFR| normalised score that bypasses soft filtering.",
40
+ "$ref": "#/definitions/probability"
41
+ },
42
+ "force_accel": {
43
+ "description": "Minimum acceleration normalised score that bypasses soft filtering.",
44
+ "$ref": "#/definitions/probability"
45
+ }
46
+ },
47
+ "additionalProperties": true
48
+ },
49
+ "cfg_canon": {
50
+ "type": "object",
51
+ "description": "Canonical grammar thresholds enforced by the automaton.",
52
+ "properties": {
53
+ "enabled": {
54
+ "description": "Toggle canonical grammar enforcement during metric runs.",
55
+ "type": "boolean"
56
+ },
57
+ "zhir_requires_oz_window": {
58
+ "description": "Window requiring a DISSONANCE glyph before a MUTATION.",
59
+ "type": "integer",
60
+ "minimum": 0
61
+ },
62
+ "zhir_dnfr_min": {
63
+ "description": "Minimum normalised |ΔNFR| required to allow MUTATION without recent DISSONANCE.",
64
+ "type": "number",
65
+ "minimum": 0.0
66
+ },
67
+ "thol_min_len": {
68
+ "description": "Minimum number of THOL glyphs before canonical closure is allowed.",
69
+ "type": "integer",
70
+ "minimum": 0
71
+ },
72
+ "thol_max_len": {
73
+ "description": "Maximum number of THOL glyphs tolerated before forcing closure.",
74
+ "type": "integer",
75
+ "minimum": 0
76
+ },
77
+ "thol_close_dnfr": {
78
+ "description": "Upper bound on normalised |ΔNFR| that triggers THOL closure.",
79
+ "$ref": "#/definitions/probability"
80
+ },
81
+ "si_high": {
82
+ "description": "Sense index threshold: Si at or above this resolves THOL closures with silence; lower Si forces contraction.",
83
+ "$ref": "#/definitions/probability"
84
+ }
85
+ },
86
+ "additionalProperties": true
87
+ }
88
+ },
89
+ "properties": {
90
+ "cfg_soft": { "$ref": "#/definitions/cfg_soft" },
91
+ "cfg_canon": { "$ref": "#/definitions/cfg_canon" }
92
+ },
93
+ "additionalProperties": false
94
+ }
tnfr/sdk/__init__.py ADDED
@@ -0,0 +1,107 @@
1
+ """Simplified SDK for non-expert TNFR users.
2
+
3
+ This module provides a high-level, user-friendly API for creating and
4
+ simulating TNFR networks without requiring deep knowledge of the underlying
5
+ theory. The SDK maintains full theoretical fidelity while hiding complexity
6
+ through fluent interfaces, pre-configured templates, and domain-specific
7
+ patterns.
8
+
9
+ Public API
10
+ ----------
11
+ TNFRNetwork
12
+ Fluent API for creating and evolving TNFR networks with method chaining.
13
+ TNFRTemplates
14
+ Pre-configured templates for common domain-specific use cases.
15
+ TNFRExperimentBuilder
16
+ Builder pattern for standard TNFR experiment workflows.
17
+ NetworkResults
18
+ Structured results container for TNFR metrics and graph state.
19
+ NetworkConfig
20
+ Configuration dataclass for network settings.
21
+
22
+ Utilities
23
+ ---------
24
+ compare_networks
25
+ Compare metrics across multiple networks.
26
+ compute_network_statistics
27
+ Compute extended statistics for a network.
28
+ export_to_json
29
+ Export network data to JSON file.
30
+ import_from_json
31
+ Import network data from JSON file.
32
+ format_comparison_table
33
+ Format network comparison as readable table.
34
+ suggest_sequence_for_goal
35
+ Suggest operator sequence for a specific goal.
36
+ """
37
+
38
+ from __future__ import annotations
39
+
40
+ __all__ = [
41
+ "TNFRNetwork",
42
+ "NetworkConfig",
43
+ "NetworkResults",
44
+ "TNFRTemplates",
45
+ "TNFRExperimentBuilder",
46
+ "TNFRAdaptiveSystem",
47
+ # Utilities
48
+ "compare_networks",
49
+ "compute_network_statistics",
50
+ "export_to_json",
51
+ "import_from_json",
52
+ "format_comparison_table",
53
+ "suggest_sequence_for_goal",
54
+ ]
55
+
56
+
57
+ # Lazy imports to avoid circular dependencies and optional dependency issues
58
+ def __getattr__(name: str):
59
+ """Lazy load SDK components."""
60
+ if name == "TNFRNetwork" or name == "NetworkConfig" or name == "NetworkResults":
61
+ from .fluent import TNFRNetwork, NetworkConfig, NetworkResults
62
+
63
+ if name == "TNFRNetwork":
64
+ return TNFRNetwork
65
+ elif name == "NetworkConfig":
66
+ return NetworkConfig
67
+ else:
68
+ return NetworkResults
69
+ elif name == "TNFRTemplates":
70
+ from .templates import TNFRTemplates
71
+
72
+ return TNFRTemplates
73
+ elif name == "TNFRExperimentBuilder":
74
+ from .builders import TNFRExperimentBuilder
75
+
76
+ return TNFRExperimentBuilder
77
+ elif name == "TNFRAdaptiveSystem":
78
+ from .adaptive_system import TNFRAdaptiveSystem
79
+
80
+ return TNFRAdaptiveSystem
81
+ elif name in [
82
+ "compare_networks",
83
+ "compute_network_statistics",
84
+ "export_to_json",
85
+ "import_from_json",
86
+ "format_comparison_table",
87
+ "suggest_sequence_for_goal",
88
+ ]:
89
+ from .utils import (
90
+ compare_networks,
91
+ compute_network_statistics,
92
+ export_to_json,
93
+ import_from_json,
94
+ format_comparison_table,
95
+ suggest_sequence_for_goal,
96
+ )
97
+
98
+ mapping = {
99
+ "compare_networks": compare_networks,
100
+ "compute_network_statistics": compute_network_statistics,
101
+ "export_to_json": export_to_json,
102
+ "import_from_json": import_from_json,
103
+ "format_comparison_table": format_comparison_table,
104
+ "suggest_sequence_for_goal": suggest_sequence_for_goal,
105
+ }
106
+ return mapping[name]
107
+ raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
tnfr/sdk/__init__.pyi ADDED
@@ -0,0 +1,19 @@
1
+ """Type stubs for tnfr.sdk module."""
2
+
3
+ from typing import Any
4
+
5
+ __all__: tuple[str, ...]
6
+
7
+ TNFRNetwork: Any
8
+ NetworkConfig: Any
9
+ NetworkResults: Any
10
+ TNFRTemplates: Any
11
+ TNFRExperimentBuilder: Any
12
+ TNFRAdaptiveSystem: Any
13
+
14
+ compare_networks: Any
15
+ compute_network_statistics: Any
16
+ export_to_json: Any
17
+ import_from_json: Any
18
+ format_comparison_table: Any
19
+ suggest_sequence_for_goal: Any
@@ -0,0 +1,173 @@
1
+ """Unified adaptive system integrating all TNFR dynamic components.
2
+
3
+ This module provides a high-level interface that combines feedback loops,
4
+ adaptive sequence selection, homeostasis, learning, and metabolism into a
5
+ single coherent adaptive system. It represents the complete implementation
6
+ of TNFR autonomous evolution.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import TYPE_CHECKING
12
+
13
+ if TYPE_CHECKING:
14
+ from ..types import TNFRGraph, NodeId
15
+
16
+ from ..alias import get_attr
17
+ from ..constants.aliases import ALIAS_DNFR
18
+ from ..dynamics.feedback import StructuralFeedbackLoop
19
+ from ..dynamics.adaptive_sequences import AdaptiveSequenceSelector
20
+ from ..dynamics.homeostasis import StructuralHomeostasis
21
+ from ..dynamics.learning import AdaptiveLearningSystem
22
+ from ..dynamics.metabolism import StructuralMetabolism
23
+
24
+ __all__ = ["TNFRAdaptiveSystem"]
25
+
26
+
27
+ class TNFRAdaptiveSystem:
28
+ """Complete adaptive system integrating all TNFR dynamic components.
29
+
30
+ This class orchestrates feedback loops, sequence selection, homeostasis,
31
+ learning, and metabolism into autonomous evolution cycles. It provides
32
+ a single entry point for complex adaptive behaviors.
33
+
34
+ **Integrated Components:**
35
+
36
+ - **Feedback Loop**: Regulates coherence via operator selection
37
+ - **Sequence Selector**: Learns optimal operator trajectories
38
+ - **Homeostasis**: Maintains parameter equilibrium
39
+ - **Learning System**: Implements AL + T'HOL learning cycles
40
+ - **Metabolism**: Digests stimuli into structure
41
+
42
+ Parameters
43
+ ----------
44
+ graph : TNFRGraph
45
+ Graph containing the evolving node
46
+ node : NodeId
47
+ Identifier of the adaptive node
48
+ stress_normalization : float, default=0.2
49
+ ΔNFR value that corresponds to maximum stress (1.0)
50
+
51
+ Attributes
52
+ ----------
53
+ G : TNFRGraph
54
+ Graph reference
55
+ node : NodeId
56
+ Node identifier
57
+ feedback : StructuralFeedbackLoop
58
+ Feedback regulation component
59
+ sequence_selector : AdaptiveSequenceSelector
60
+ Adaptive sequence selection component
61
+ homeostasis : StructuralHomeostasis
62
+ Homeostatic regulation component
63
+ learning : AdaptiveLearningSystem
64
+ Adaptive learning component
65
+ metabolism : StructuralMetabolism
66
+ Structural metabolism component
67
+ STRESS_NORM : float
68
+ Normalization factor for stress measurement
69
+
70
+ Examples
71
+ --------
72
+ >>> from tnfr.structural import create_nfr
73
+ >>> from tnfr.sdk.adaptive_system import TNFRAdaptiveSystem
74
+ >>> G, node = create_nfr("adaptive_node")
75
+ >>> system = TNFRAdaptiveSystem(G, node)
76
+ >>> system.autonomous_evolution(num_cycles=20)
77
+
78
+ Notes
79
+ -----
80
+ The adaptive system implements complete TNFR autonomous evolution as
81
+ specified in the operational manual. Each cycle integrates:
82
+
83
+ 1. Homeostatic regulation
84
+ 2. Feedback-driven operator selection
85
+ 3. Metabolic stress response
86
+ 4. Learning consolidation
87
+
88
+ This creates self-regulating, adaptive structural dynamics.
89
+ """
90
+
91
+ STRESS_NORM = 0.2 # ΔNFR value corresponding to maximum stress
92
+
93
+ def __init__(
94
+ self,
95
+ graph: TNFRGraph,
96
+ node: NodeId,
97
+ stress_normalization: float = STRESS_NORM,
98
+ ) -> None:
99
+ self.G = graph
100
+ self.node = node
101
+ self.STRESS_NORM = float(stress_normalization)
102
+
103
+ # Initialize all components
104
+ self.feedback = StructuralFeedbackLoop(graph, node)
105
+ self.sequence_selector = AdaptiveSequenceSelector(graph, node)
106
+ self.homeostasis = StructuralHomeostasis(graph, node)
107
+ self.learning = AdaptiveLearningSystem(graph, node)
108
+ self.metabolism = StructuralMetabolism(graph, node)
109
+
110
+ def autonomous_evolution(self, num_cycles: int = 20) -> None:
111
+ """Execute complete autonomous evolution cycles.
112
+
113
+ Each cycle integrates adaptive components:
114
+
115
+ 1. **Homeostasis**: Correct out-of-range parameters
116
+ 2. **Feedback**: Regulate coherence via operator selection
117
+
118
+ Parameters
119
+ ----------
120
+ num_cycles : int, default=20
121
+ Number of evolution cycles to execute
122
+
123
+ Notes
124
+ -----
125
+ The integration follows TNFR principles:
126
+
127
+ - **Homeostasis first**: Ensure safe operating parameters
128
+ - **Feedback loops**: Maintain target coherence
129
+
130
+ This creates robust, adaptive, self-regulating dynamics.
131
+
132
+ **Advanced Usage:**
133
+
134
+ For full metabolic and learning cycles, use the component systems
135
+ directly:
136
+
137
+ - ``system.metabolism.adaptive_metabolism(stress)``
138
+ - ``system.learning.consolidate_memory()``
139
+
140
+ These require careful sequence design to comply with TNFR grammar.
141
+ """
142
+ for cycle in range(num_cycles):
143
+ # 1. Homeostatic regulation: maintain parameter equilibrium
144
+ self.homeostasis.maintain_equilibrium()
145
+
146
+ # 2. Feedback loop: regulate coherence
147
+ self.feedback.homeostatic_cycle(num_steps=3)
148
+
149
+ def _measure_stress(self) -> float:
150
+ """Measure structural stress level from ΔNFR.
151
+
152
+ Stress is proportional to reorganization pressure. High ΔNFR
153
+ indicates high stress requiring metabolic response.
154
+
155
+ Returns
156
+ -------
157
+ float
158
+ Stress level normalized to [0, 1]
159
+
160
+ Notes
161
+ -----
162
+ Stress mapping:
163
+
164
+ - ΔNFR = 0.0 → stress = 0.0 (no pressure)
165
+ - ΔNFR = 0.2 → stress = 1.0 (maximum pressure)
166
+ - Linear interpolation between
167
+
168
+ This normalization allows consistent stress response across
169
+ different system scales.
170
+ """
171
+ dnfr = get_attr(self.G.nodes[self.node], ALIAS_DNFR, 0.0)
172
+ # Normalize ΔNFR to [0, 1] stress level
173
+ return min(1.0, abs(dnfr) / self.STRESS_NORM)
@@ -0,0 +1,21 @@
1
+ """Type stubs for tnfr.sdk.adaptive_system module."""
2
+
3
+ from ..types import TNFRGraph, NodeId
4
+ from ..dynamics.feedback import StructuralFeedbackLoop
5
+ from ..dynamics.adaptive_sequences import AdaptiveSequenceSelector
6
+ from ..dynamics.homeostasis import StructuralHomeostasis
7
+ from ..dynamics.learning import AdaptiveLearningSystem
8
+ from ..dynamics.metabolism import StructuralMetabolism
9
+
10
+ class TNFRAdaptiveSystem:
11
+ G: TNFRGraph
12
+ node: NodeId
13
+ feedback: StructuralFeedbackLoop
14
+ sequence_selector: AdaptiveSequenceSelector
15
+ homeostasis: StructuralHomeostasis
16
+ learning: AdaptiveLearningSystem
17
+ metabolism: StructuralMetabolism
18
+
19
+ def __init__(self, graph: TNFRGraph, node: NodeId) -> None: ...
20
+ def autonomous_evolution(self, num_cycles: int = ...) -> None: ...
21
+ def _measure_stress(self) -> float: ...