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
@@ -0,0 +1,460 @@
1
+ """Canonical TNFR compatibility tables expressed via structural operators."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from enum import Enum
6
+
7
+ from ..config.operator_names import (
8
+ COHERENCE,
9
+ CONTRACTION,
10
+ COUPLING,
11
+ DISSONANCE,
12
+ EMISSION,
13
+ EXPANSION,
14
+ MUTATION,
15
+ RECEPTION,
16
+ RECURSIVITY,
17
+ RESONANCE,
18
+ SELF_ORGANIZATION,
19
+ SILENCE,
20
+ TRANSITION,
21
+ )
22
+ from ..operators import grammar as _grammar
23
+ from ..types import Glyph
24
+
25
+ __all__ = [
26
+ "CANON_COMPAT",
27
+ "CANON_FALLBACK",
28
+ "CompatibilityLevel",
29
+ "GRADUATED_COMPATIBILITY",
30
+ "get_compatibility_level",
31
+ ]
32
+
33
+
34
+ class CompatibilityLevel(Enum):
35
+ """Graduated compatibility levels for structural operator transitions.
36
+
37
+ Reflects the theoretical richness of TNFR by distinguishing between
38
+ optimal, acceptable, contextual, and incompatible transitions.
39
+
40
+ Attributes
41
+ ----------
42
+ EXCELLENT : str
43
+ Optimal transition that directly supports structural coherence.
44
+ Example: EMISSION → COHERENCE (initiation → stabilization)
45
+ GOOD : str
46
+ Acceptable transition that maintains structural integrity.
47
+ Example: EMISSION → RESONANCE (initiation → amplification)
48
+ CAUTION : str
49
+ Contextually dependent transition requiring careful validation.
50
+ Example: EMISSION → DISSONANCE (initiation → tension)
51
+ Generates warnings to alert users of potential incoherence.
52
+ AVOID : str
53
+ Incompatible transition that violates structural coherence.
54
+ Example: SILENCE → DISSONANCE (pause → tension is contradictory)
55
+ Raises SequenceSyntaxError when encountered.
56
+ """
57
+
58
+ EXCELLENT = "excellent"
59
+ GOOD = "good"
60
+ CAUTION = "caution"
61
+ AVOID = "avoid"
62
+
63
+
64
+ # Graduated compatibility matrix expressing structural operator transition quality
65
+ # Maps each operator to its allowed next operators categorized by compatibility level
66
+ GRADUATED_COMPATIBILITY: dict[str, dict[str, list[str]]] = {
67
+ # EMISSION (AL) - Initiates resonant patterns, seeds coherence outward
68
+ EMISSION: {
69
+ "excellent": [
70
+ COHERENCE,
71
+ TRANSITION,
72
+ RECEPTION,
73
+ ], # Initiation → stabilization/handoff/anchoring
74
+ "good": [RESONANCE, EXPANSION, COUPLING], # Amplification, exploration, linking
75
+ "caution": [DISSONANCE], # Direct tension after initiation requires context
76
+ "avoid": [
77
+ SILENCE,
78
+ EMISSION,
79
+ MUTATION,
80
+ CONTRACTION,
81
+ SELF_ORGANIZATION,
82
+ RECURSIVITY,
83
+ ],
84
+ },
85
+ # RECEPTION (EN) - Anchors inbound energy into the EPI
86
+ RECEPTION: {
87
+ "excellent": [
88
+ COHERENCE,
89
+ COUPLING,
90
+ SELF_ORGANIZATION,
91
+ ], # Anchoring → stabilization/linking/autonomous cascades
92
+ "good": [RESONANCE], # Amplification after receiving
93
+ "caution": [],
94
+ "avoid": [
95
+ SILENCE,
96
+ EMISSION,
97
+ DISSONANCE,
98
+ EXPANSION,
99
+ CONTRACTION,
100
+ MUTATION,
101
+ TRANSITION,
102
+ RECURSIVITY,
103
+ RECEPTION,
104
+ ],
105
+ },
106
+ # COHERENCE (IL) - Compresses ΔNFR drift to stabilize C(t)
107
+ COHERENCE: {
108
+ "excellent": [
109
+ RESONANCE,
110
+ EXPANSION,
111
+ COUPLING,
112
+ ], # Stability → amplification/exploration/linking
113
+ "good": [
114
+ SILENCE,
115
+ TRANSITION,
116
+ CONTRACTION,
117
+ SELF_ORGANIZATION,
118
+ RECURSIVITY,
119
+ ], # Valid progressions
120
+ "caution": [
121
+ MUTATION,
122
+ DISSONANCE,
123
+ ], # Post-stabilization tension/mutation needs context
124
+ "avoid": [
125
+ EMISSION,
126
+ RECEPTION,
127
+ COHERENCE,
128
+ ], # Cannot re-initiate, re-anchor, or re-stabilize
129
+ },
130
+ # DISSONANCE (OZ) - Injects controlled tension for probes
131
+ DISSONANCE: {
132
+ "excellent": [
133
+ MUTATION,
134
+ TRANSITION,
135
+ SELF_ORGANIZATION,
136
+ ], # Tension → transformation/handoff/reorganization
137
+ "good": [
138
+ CONTRACTION,
139
+ RESONANCE,
140
+ RECURSIVITY,
141
+ COHERENCE,
142
+ ], # Concentration, amplification, fractal echo, stabilization
143
+ "caution": [DISSONANCE], # Repeated dissonance needs careful management
144
+ "avoid": [SILENCE, EMISSION, RECEPTION, COUPLING, EXPANSION],
145
+ },
146
+ # COUPLING (UM) - Synchronizes bidirectional coherence links
147
+ COUPLING: {
148
+ "excellent": [
149
+ RESONANCE,
150
+ COHERENCE,
151
+ EXPANSION,
152
+ ], # Linking → amplification/stabilization/exploration
153
+ "good": [TRANSITION, SILENCE], # Handoff or pause after coupling
154
+ "caution": [],
155
+ "avoid": [
156
+ EMISSION,
157
+ RECEPTION,
158
+ DISSONANCE,
159
+ CONTRACTION,
160
+ MUTATION,
161
+ SELF_ORGANIZATION,
162
+ RECURSIVITY,
163
+ COUPLING,
164
+ ],
165
+ },
166
+ # RESONANCE (RA) - Amplifies aligned structural frequency
167
+ RESONANCE: {
168
+ "excellent": [
169
+ COHERENCE,
170
+ EXPANSION,
171
+ COUPLING,
172
+ ], # Amplification → stabilization/exploration/linking
173
+ "good": [
174
+ TRANSITION,
175
+ SILENCE,
176
+ EMISSION,
177
+ RECURSIVITY,
178
+ ], # Handoff, pause, re-initiation, fractal echo
179
+ "caution": [],
180
+ "avoid": [
181
+ RECEPTION,
182
+ DISSONANCE,
183
+ CONTRACTION,
184
+ MUTATION,
185
+ SELF_ORGANIZATION,
186
+ RESONANCE,
187
+ ],
188
+ },
189
+ # SILENCE (SHA) - Suspends reorganization while preserving form
190
+ SILENCE: {
191
+ "excellent": [
192
+ EMISSION,
193
+ RECEPTION,
194
+ ], # Resume from pause → initiation or anchoring
195
+ "good": [],
196
+ "caution": [],
197
+ "avoid": [
198
+ COHERENCE,
199
+ DISSONANCE,
200
+ COUPLING,
201
+ RESONANCE,
202
+ EXPANSION,
203
+ CONTRACTION,
204
+ MUTATION,
205
+ TRANSITION,
206
+ SELF_ORGANIZATION,
207
+ RECURSIVITY,
208
+ SILENCE,
209
+ ],
210
+ },
211
+ # EXPANSION (VAL) - Dilates structure to explore volume
212
+ EXPANSION: {
213
+ "excellent": [
214
+ COUPLING,
215
+ RESONANCE,
216
+ COHERENCE,
217
+ ], # Exploration → linking/amplification/stabilization
218
+ "good": [TRANSITION], # Handoff after expansion
219
+ "caution": [],
220
+ "avoid": [
221
+ EMISSION,
222
+ RECEPTION,
223
+ DISSONANCE,
224
+ SILENCE,
225
+ CONTRACTION,
226
+ MUTATION,
227
+ SELF_ORGANIZATION,
228
+ RECURSIVITY,
229
+ EXPANSION,
230
+ ],
231
+ },
232
+ # CONTRACTION (NUL) - Concentrates trajectories into core
233
+ CONTRACTION: {
234
+ "excellent": [
235
+ EMISSION,
236
+ COHERENCE,
237
+ ], # Concentration → re-initiation or stabilization
238
+ "good": [],
239
+ "caution": [],
240
+ "avoid": [
241
+ RECEPTION,
242
+ DISSONANCE,
243
+ COUPLING,
244
+ RESONANCE,
245
+ SILENCE,
246
+ EXPANSION,
247
+ MUTATION,
248
+ TRANSITION,
249
+ SELF_ORGANIZATION,
250
+ RECURSIVITY,
251
+ CONTRACTION,
252
+ ],
253
+ },
254
+ # SELF_ORGANIZATION (THOL) - Spawns autonomous cascades
255
+ SELF_ORGANIZATION: {
256
+ "excellent": [
257
+ COHERENCE,
258
+ COUPLING,
259
+ RESONANCE,
260
+ ], # Autonomous cascades → stabilization/linking/amplification
261
+ "good": [
262
+ DISSONANCE,
263
+ MUTATION,
264
+ TRANSITION,
265
+ SILENCE,
266
+ CONTRACTION,
267
+ EMISSION,
268
+ SELF_ORGANIZATION,
269
+ ], # Nested/sequential self-organization
270
+ "caution": [],
271
+ "avoid": [RECEPTION, EXPANSION, RECURSIVITY],
272
+ },
273
+ # MUTATION (ZHIR) - Pivots node across structural thresholds
274
+ MUTATION: {
275
+ "excellent": [
276
+ COHERENCE,
277
+ TRANSITION,
278
+ SILENCE,
279
+ ], # Transformation → stabilization/handoff/pause
280
+ "good": [],
281
+ "caution": [],
282
+ "avoid": [
283
+ EMISSION,
284
+ RECEPTION,
285
+ DISSONANCE,
286
+ COUPLING,
287
+ RESONANCE,
288
+ EXPANSION,
289
+ CONTRACTION,
290
+ MUTATION,
291
+ SELF_ORGANIZATION,
292
+ RECURSIVITY,
293
+ ],
294
+ },
295
+ # TRANSITION (NAV) - Guides controlled regime hand-offs
296
+ TRANSITION: {
297
+ "excellent": [
298
+ RESONANCE,
299
+ COHERENCE,
300
+ COUPLING,
301
+ ], # Handoff → amplification/stabilization/linking
302
+ "good": [
303
+ DISSONANCE,
304
+ MUTATION,
305
+ SILENCE,
306
+ TRANSITION,
307
+ ], # Tension, transformation, pause, continued handoff
308
+ "caution": [],
309
+ "avoid": [
310
+ EMISSION,
311
+ RECEPTION,
312
+ EXPANSION,
313
+ CONTRACTION,
314
+ SELF_ORGANIZATION,
315
+ RECURSIVITY,
316
+ ],
317
+ },
318
+ # RECURSIVITY (REMESH) - Echoes patterns across nested EPIs
319
+ RECURSIVITY: {
320
+ "excellent": [
321
+ COHERENCE,
322
+ RESONANCE,
323
+ ], # Fractal echo → stabilization/amplification
324
+ "good": [
325
+ DISSONANCE,
326
+ RECEPTION,
327
+ COUPLING,
328
+ TRANSITION,
329
+ ], # Tension, anchoring, linking, handoff after recursive pattern
330
+ "caution": [],
331
+ "avoid": [
332
+ EMISSION,
333
+ SILENCE,
334
+ EXPANSION,
335
+ CONTRACTION,
336
+ MUTATION,
337
+ SELF_ORGANIZATION,
338
+ RECURSIVITY,
339
+ ],
340
+ },
341
+ }
342
+
343
+
344
+ def get_compatibility_level(prev: str, next_op: str) -> CompatibilityLevel:
345
+ """Return the compatibility level between two structural operators.
346
+
347
+ Parameters
348
+ ----------
349
+ prev : str
350
+ Previous operator in canonical form (e.g., "emission", "coherence").
351
+ next_op : str
352
+ Next operator in canonical form (e.g., "dissonance", "resonance").
353
+
354
+ Returns
355
+ -------
356
+ CompatibilityLevel
357
+ The graduated compatibility level: EXCELLENT, GOOD, CAUTION, or AVOID.
358
+
359
+ Examples
360
+ --------
361
+ >>> get_compatibility_level("emission", "coherence")
362
+ CompatibilityLevel.EXCELLENT
363
+
364
+ >>> get_compatibility_level("emission", "dissonance")
365
+ CompatibilityLevel.CAUTION
366
+
367
+ >>> get_compatibility_level("silence", "dissonance")
368
+ CompatibilityLevel.AVOID
369
+
370
+ Notes
371
+ -----
372
+ This function implements the graduated compatibility matrix following TNFR
373
+ canonical theory. Transitions are categorized as:
374
+
375
+ - EXCELLENT: Optimal structural progression
376
+ - GOOD: Acceptable structural progression
377
+ - CAUTION: Contextually dependent, requires validation
378
+ - AVOID: Incompatible, violates structural coherence
379
+ """
380
+ if prev not in GRADUATED_COMPATIBILITY:
381
+ # Unknown operator defaults to AVOID
382
+ return CompatibilityLevel.AVOID
383
+
384
+ levels = GRADUATED_COMPATIBILITY[prev]
385
+
386
+ # Check each level in order of preference
387
+ if next_op in levels.get("excellent", []):
388
+ return CompatibilityLevel.EXCELLENT
389
+ elif next_op in levels.get("good", []):
390
+ return CompatibilityLevel.GOOD
391
+ elif next_op in levels.get("caution", []):
392
+ return CompatibilityLevel.CAUTION
393
+ else:
394
+ return CompatibilityLevel.AVOID
395
+
396
+
397
+ # Generate backward-compatible binary compatibility table from graduated matrix
398
+ # This combines excellent, good, and caution levels as "allowed" transitions
399
+ def _generate_binary_compat() -> dict[str, set[str]]:
400
+ """Generate binary compatibility table from graduated matrix.
401
+
402
+ Combines EXCELLENT, GOOD, and CAUTION levels into a single "allowed" set
403
+ for backward compatibility with existing code that expects binary validation.
404
+ """
405
+ compat: dict[str, set[str]] = {}
406
+ for operator, levels in GRADUATED_COMPATIBILITY.items():
407
+ allowed = set()
408
+ allowed.update(levels.get("excellent", []))
409
+ allowed.update(levels.get("good", []))
410
+ allowed.update(levels.get("caution", []))
411
+ compat[operator] = allowed
412
+ return compat
413
+
414
+
415
+ # Canonical compatibilities (allowed next operators) expressed via structural names
416
+ # Derived from GRADUATED_COMPATIBILITY for backward compatibility
417
+ _STRUCTURAL_COMPAT: dict[str, set[str]] = _generate_binary_compat()
418
+
419
+
420
+ def _name_to_glyph(name: str) -> Glyph:
421
+ glyph = _grammar.function_name_to_glyph(name)
422
+ if glyph is None:
423
+ raise KeyError(f"No glyph mapped to structural operator '{name}'")
424
+ return glyph
425
+
426
+
427
+ def _translate_structural() -> tuple[dict[Glyph, set[Glyph]], dict[Glyph, Glyph]]:
428
+ compat: dict[Glyph, set[Glyph]] = {}
429
+ for src, targets in _STRUCTURAL_COMPAT.items():
430
+ src_glyph = _name_to_glyph(src)
431
+ compat[src_glyph] = {_name_to_glyph(target) for target in targets}
432
+ fallback: dict[Glyph, Glyph] = {}
433
+ for src, target in _STRUCTURAL_FALLBACK.items():
434
+ fallback[_name_to_glyph(src)] = _name_to_glyph(target)
435
+ return compat, fallback
436
+
437
+
438
+ # Canonical fallbacks when a transition is not allowed (structural names)
439
+ _STRUCTURAL_FALLBACK: dict[str, str] = {
440
+ EMISSION: RECEPTION,
441
+ RECEPTION: COHERENCE,
442
+ COHERENCE: RESONANCE,
443
+ TRANSITION: RESONANCE,
444
+ CONTRACTION: EMISSION,
445
+ DISSONANCE: MUTATION,
446
+ RESONANCE: COHERENCE,
447
+ SILENCE: EMISSION,
448
+ SELF_ORGANIZATION: TRANSITION,
449
+ COUPLING: RESONANCE,
450
+ EXPANSION: RESONANCE,
451
+ MUTATION: COHERENCE,
452
+ RECURSIVITY: COHERENCE, # Fractal echo → stabilization
453
+ }
454
+
455
+ CANON_COMPAT, CANON_FALLBACK = _translate_structural()
456
+
457
+ # Re-export structural tables for internal consumers that operate on functional
458
+ # identifiers without exposing them as part of the public API.
459
+ _STRUCTURAL_COMPAT_TABLE = _STRUCTURAL_COMPAT
460
+ _STRUCTURAL_FALLBACK_TABLE = _STRUCTURAL_FALLBACK
@@ -0,0 +1,6 @@
1
+ from ..types import Glyph
2
+
3
+ __all__ = ("CANON_COMPAT", "CANON_FALLBACK")
4
+
5
+ CANON_COMPAT: dict[Glyph, set[Glyph]]
6
+ CANON_FALLBACK: dict[Glyph, Glyph]
@@ -0,0 +1,73 @@
1
+ """Configuration for TNFR validation system.
2
+
3
+ This module provides configuration options for controlling validation behavior,
4
+ including thresholds, performance settings, and validation levels.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import math
10
+ from dataclasses import dataclass
11
+
12
+ from .invariants import InvariantSeverity
13
+
14
+ __all__ = [
15
+ "ValidationConfig",
16
+ "validation_config",
17
+ "configure_validation",
18
+ ]
19
+
20
+
21
+ @dataclass
22
+ class ValidationConfig:
23
+ """TNFR validation system configuration."""
24
+
25
+ # Validation levels
26
+ validate_invariants: bool = True
27
+ validate_each_step: bool = False # Expensive, only for debugging
28
+ min_severity: InvariantSeverity = InvariantSeverity.ERROR
29
+
30
+ # Numerical thresholds (can be overridden from graph.graph config)
31
+ epi_range: tuple[float, float] = (0.0, 1.0)
32
+ vf_range: tuple[float, float] = (0.001, 1000.0) # Hz_str
33
+ phase_coupling_threshold: float = math.pi / 2
34
+
35
+ # Semantic validation
36
+ enable_semantic_validation: bool = True
37
+ allow_semantic_warnings: bool = True
38
+
39
+ # Performance
40
+ cache_validation_results: bool = False # Future optimization
41
+ max_validation_time_ms: float = 1000.0 # Timeout (not implemented yet)
42
+
43
+
44
+ # Global configuration
45
+ validation_config = ValidationConfig()
46
+
47
+
48
+ def configure_validation(**kwargs: object) -> None:
49
+ """Updates global validation configuration.
50
+
51
+ Parameters
52
+ ----------
53
+ **kwargs
54
+ Configuration parameters to update. Valid keys match
55
+ ValidationConfig attributes.
56
+
57
+ Raises
58
+ ------
59
+ ValueError
60
+ If an unknown configuration key is provided.
61
+
62
+ Examples
63
+ --------
64
+ >>> from tnfr.validation.config import configure_validation
65
+ >>> configure_validation(validate_each_step=True)
66
+ >>> configure_validation(phase_coupling_threshold=3.14159/3)
67
+ """
68
+ global validation_config
69
+ for key, value in kwargs.items():
70
+ if hasattr(validation_config, key):
71
+ setattr(validation_config, key, value)
72
+ else:
73
+ raise ValueError(f"Unknown validation config key: {key}")
@@ -0,0 +1,139 @@
1
+ """Graph-level validation helpers enforcing TNFR invariants."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from collections.abc import Sequence
7
+
8
+ import numpy as np
9
+
10
+ from ..alias import get_attr
11
+ from ..glyph_runtime import last_glyph
12
+ from ..config.constants import GLYPHS_CANONICAL_SET
13
+ from ..constants import get_param
14
+ from ..constants.aliases import ALIAS_EPI, ALIAS_VF
15
+ from ..utils import within_range
16
+ from ..types import (
17
+ EPIValue,
18
+ NodeAttrMap,
19
+ NodeId,
20
+ StructuralFrequency,
21
+ TNFRGraph,
22
+ ValidatorFunc,
23
+ ensure_bepi,
24
+ )
25
+
26
+ NodeData = NodeAttrMap
27
+ """Read-only node attribute mapping used by validators."""
28
+
29
+ AliasSequence = Sequence[str]
30
+ """Sequence of accepted attribute aliases."""
31
+
32
+ __all__ = ("run_validators", "GRAPH_VALIDATORS")
33
+
34
+
35
+ def _materialize_node_mapping(data: NodeData) -> dict[str, object]:
36
+ if isinstance(data, dict):
37
+ return data
38
+ return dict(data)
39
+
40
+
41
+ def _require_attr(
42
+ data: NodeData, alias: AliasSequence, node: NodeId, name: str
43
+ ) -> float:
44
+ """Return scalar attribute value or raise if missing."""
45
+
46
+ mapping = _materialize_node_mapping(data)
47
+ val = get_attr(mapping, alias, None)
48
+ if val is None:
49
+ raise ValueError(f"Missing {name} attribute in node {node}")
50
+ return float(val)
51
+
52
+
53
+ def _require_epi(data: NodeData, node: NodeId) -> EPIValue:
54
+ """Return a validated BEPI element stored in ``data``."""
55
+
56
+ mapping = _materialize_node_mapping(data)
57
+ value = get_attr(mapping, ALIAS_EPI, None, conv=lambda obj: obj)
58
+ if value is None:
59
+ raise ValueError(f"Missing EPI attribute in node {node}")
60
+ try:
61
+ return ensure_bepi(value)
62
+ except (TypeError, ValueError) as exc:
63
+ raise ValueError(f"Invalid EPI payload in node {node}: {exc}") from exc
64
+
65
+
66
+ def _validate_sigma(graph: TNFRGraph) -> None:
67
+ from ..sense import sigma_vector_from_graph
68
+
69
+ sv = sigma_vector_from_graph(graph)
70
+ if sv.get("mag", 0.0) > 1.0 + sys.float_info.epsilon:
71
+ raise ValueError("σ norm exceeds 1")
72
+
73
+
74
+ GRAPH_VALIDATORS: tuple[ValidatorFunc, ...] = (_validate_sigma,)
75
+ """Ordered collection of graph-level validators."""
76
+
77
+
78
+ def _max_abs(values: np.ndarray) -> float:
79
+ if values.size == 0:
80
+ return 0.0
81
+ return float(np.max(np.abs(values)))
82
+
83
+
84
+ def _check_epi(
85
+ epi: EPIValue,
86
+ epi_min: float,
87
+ epi_max: float,
88
+ node: NodeId,
89
+ ) -> None:
90
+ continuous_max = _max_abs(epi.f_continuous)
91
+ discrete_max = _max_abs(epi.a_discrete)
92
+ _check_range(continuous_max, epi_min, epi_max, "EPI continuous", node)
93
+ _check_range(discrete_max, epi_min, epi_max, "EPI discrete", node)
94
+
95
+ spacings = np.diff(epi.x_grid)
96
+ if np.any(spacings <= 0.0):
97
+ raise ValueError(f"EPI grid must be strictly increasing for node {node}")
98
+ if not np.allclose(spacings, spacings[0], rtol=1e-9, atol=1e-12):
99
+ raise ValueError(f"EPI grid must be uniform for node {node}")
100
+
101
+
102
+ def _out_of_range_msg(name: str, node: NodeId, val: float) -> str:
103
+ return f"{name} out of range in node {node}: {val}"
104
+
105
+
106
+ def _check_range(
107
+ val: float,
108
+ lower: float,
109
+ upper: float,
110
+ name: str,
111
+ node: NodeId,
112
+ tol: float = 1e-9,
113
+ ) -> None:
114
+ if not within_range(val, lower, upper, tol):
115
+ raise ValueError(_out_of_range_msg(name, node, val))
116
+
117
+
118
+ def _check_glyph(glyph: str | None, node: NodeId) -> None:
119
+ if glyph and glyph not in GLYPHS_CANONICAL_SET:
120
+ raise KeyError(f"Invalid glyph {glyph} in node {node}")
121
+
122
+
123
+ def run_validators(graph: TNFRGraph) -> None:
124
+ """Run all invariant validators on ``graph`` with a single node pass."""
125
+
126
+ epi_min = float(get_param(graph, "EPI_MIN"))
127
+ epi_max = float(get_param(graph, "EPI_MAX"))
128
+ vf_min = float(get_param(graph, "VF_MIN"))
129
+ vf_max = float(get_param(graph, "VF_MAX"))
130
+
131
+ for node, data in graph.nodes(data=True):
132
+ epi = _require_epi(data, node)
133
+ vf = StructuralFrequency(_require_attr(data, ALIAS_VF, node, "VF"))
134
+ _check_epi(epi, epi_min, epi_max, node)
135
+ _check_range(vf, vf_min, vf_max, "VF", node)
136
+ _check_glyph(last_glyph(data), node)
137
+
138
+ for validator in GRAPH_VALIDATORS:
139
+ validator(graph)
@@ -0,0 +1,18 @@
1
+ from collections.abc import Sequence
2
+ from typing import Tuple
3
+
4
+ from ..types import (
5
+ EPIValue,
6
+ NodeAttrMap,
7
+ NodeId,
8
+ StructuralFrequency,
9
+ TNFRGraph,
10
+ ValidatorFunc,
11
+ )
12
+
13
+ NodeData = NodeAttrMap
14
+ AliasSequence = Sequence[str]
15
+
16
+ GRAPH_VALIDATORS: Tuple[ValidatorFunc, ...]
17
+
18
+ def run_validators(graph: TNFRGraph) -> None: ...