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,31 @@
1
+ from typing import Any
2
+
3
+ Operator: Any
4
+ Emission: Any
5
+ Reception: Any
6
+ Coherence: Any
7
+ Dissonance: Any
8
+ Coupling: Any
9
+ Resonance: Any
10
+ Silence: Any
11
+ Expansion: Any
12
+ Contraction: Any
13
+ SelfOrganization: Any
14
+ Mutation: Any
15
+ Transition: Any
16
+ Recursivity: Any
17
+ GLYPH_OPERATIONS: Any
18
+ JitterCache: Any
19
+ JitterCacheManager: Any
20
+ OPERATORS: Any
21
+ apply_glyph: Any
22
+ apply_glyph_obj: Any
23
+ apply_network_remesh: Any
24
+ apply_remesh_if_globally_stable: Any
25
+ apply_topological_remesh: Any
26
+ discover_operators: Any
27
+ get_glyph_factors: Any
28
+ get_jitter_manager: Any
29
+ get_neighbor_epi: Any
30
+ random_jitter: Any
31
+ reset_jitter_manager: Any
@@ -0,0 +1,277 @@
1
+ """Algebraic properties and validation for TNFR structural operators.
2
+
3
+ Based on TNFR.pdf Section 3.2.4 - "Notación funcional de operadores glíficos".
4
+
5
+ This module implements formal validation of algebraic properties for structural
6
+ operators in the TNFR glyphic algebra, particularly focusing on SHA (Silence)
7
+ as the identity element in structural composition.
8
+
9
+ Theoretical Foundation
10
+ ----------------------
11
+ From TNFR.pdf §3.2.4 (p. 227-230) and the nodal equation ∂EPI/∂t = νf · ΔNFR(t):
12
+
13
+ 1. **SHA as Structural Identity**:
14
+ SHA(g(ω)) ≈ g(ω) for structure (EPI)
15
+
16
+ Physical basis: SHA reduces νf → 0, making ∂EPI/∂t → 0. This freezes
17
+ structural evolution, preserving whatever structure g created.
18
+
19
+ 2. **Idempotence**:
20
+ SHA^n = SHA for all n ≥ 1
21
+
22
+ Physical basis: Once νf ≈ 0, further SHA applications cannot reduce it more.
23
+ The effect is saturated.
24
+
25
+ 3. **Commutativity with NUL**:
26
+ SHA ∘ NUL = NUL ∘ SHA
27
+
28
+ Physical basis: SHA and NUL reduce orthogonal dimensions (νf vs EPI complexity).
29
+ Order of reduction doesn't affect final state.
30
+
31
+ Category Theory Context
32
+ -----------------------
33
+ In the categorical framework (p. 231), SHA acts as identity morphism for
34
+ the structural component:
35
+ - Objects: Nodal configurations ω_i
36
+ - Morphisms: Structural operators g: ω_i → ω_j
37
+ - Identity: SHA: ω → ω (preserves structure)
38
+ - Property: SHA ∘ g ≈ g (for EPI component)
39
+
40
+ Note: SHA is NOT full identity (it modifies νf). It's identity for the
41
+ structural aspect (EPI), not the dynamic aspect (νf).
42
+ """
43
+
44
+ from __future__ import annotations
45
+
46
+ from typing import TYPE_CHECKING
47
+
48
+ if TYPE_CHECKING:
49
+ from ..types import TNFRGraph, NodeId
50
+ from .definitions import Operator
51
+
52
+ __all__ = [
53
+ "validate_identity_property",
54
+ "validate_idempotence",
55
+ "validate_commutativity_nul",
56
+ ]
57
+
58
+
59
+ def validate_identity_property(
60
+ G: TNFRGraph,
61
+ node: NodeId,
62
+ operator: Operator,
63
+ tolerance: float = 0.01,
64
+ ) -> bool:
65
+ """Validate that SHA acts as identity for structure after operator.
66
+
67
+ Tests the algebraic property: SHA(g(ω)) ≈ g(ω) for EPI
68
+
69
+ This validates that applying SHA preserves the structural state (EPI)
70
+ achieved by the operator. SHA acts as a "pause" that freezes νf but
71
+ does not alter the structural form EPI.
72
+
73
+ Physical basis: From ∂EPI/∂t = νf · ΔNFR, when SHA reduces νf → 0,
74
+ structural evolution stops but current structure is preserved.
75
+
76
+ Parameters
77
+ ----------
78
+ G : TNFRGraph
79
+ Graph containing the node to validate
80
+ node : NodeId
81
+ Target node identifier
82
+ operator : Operator
83
+ Operator to test with SHA (must be valid generator like Emission)
84
+ tolerance : float, optional
85
+ Numerical tolerance for EPI comparison (default: 0.01)
86
+ Relaxed due to grammar-required intermediate operators
87
+
88
+ Returns
89
+ -------
90
+ bool
91
+ True if identity property holds within tolerance
92
+
93
+ Notes
94
+ -----
95
+ Due to TNFR grammar constraints (C1: must end with terminator,
96
+ C2: must include stabilizer), we test identity by comparing:
97
+
98
+ - Path 1: operator → Coherence → Dissonance (OZ terminator)
99
+ - Path 2: operator → Coherence → Silence (SHA terminator)
100
+
101
+ Both preserve structure after Coherence. If SHA is identity,
102
+ EPI should be equivalent in both paths.
103
+
104
+ Examples
105
+ --------
106
+ >>> from tnfr.structural import create_nfr
107
+ >>> from tnfr.operators.definitions import Emission
108
+ >>> from tnfr.operators.algebra import validate_identity_property
109
+ >>> G, node = create_nfr("test", epi=0.5, vf=1.0)
110
+ >>> validate_identity_property(G, node, Emission()) # doctest: +SKIP
111
+ True
112
+ """
113
+ from ..alias import get_attr
114
+ from ..constants.aliases import ALIAS_EPI
115
+ from .definitions import Silence, Coherence, Dissonance
116
+ from ..structural import run_sequence
117
+
118
+ # Path 1: operator → Coherence → Dissonance (without SHA)
119
+ # Valid grammar: generator → stabilizer → terminator
120
+ G1 = G.copy()
121
+ run_sequence(G1, node, [operator, Coherence(), Dissonance()])
122
+ epi_without_sha = float(get_attr(G1.nodes[node], ALIAS_EPI, 0.0))
123
+
124
+ # Path 2: operator → Coherence → Silence (SHA as terminator)
125
+ # Valid grammar: generator → stabilizer → terminator
126
+ G2 = G.copy()
127
+ run_sequence(G2, node, [operator, Coherence(), Silence()])
128
+ epi_with_sha = float(get_attr(G2.nodes[node], ALIAS_EPI, 0.0))
129
+
130
+ # SHA should preserve the structural result (EPI) from operator → coherence
131
+ # Both terminators should leave structure intact after stabilization
132
+ return abs(epi_without_sha - epi_with_sha) < tolerance
133
+
134
+
135
+ def validate_idempotence(
136
+ G: TNFRGraph,
137
+ node: NodeId,
138
+ tolerance: float = 0.05,
139
+ ) -> bool:
140
+ """Validate that SHA is idempotent: SHA^n = SHA.
141
+
142
+ Tests the algebraic property: SHA(SHA(ω)) ≈ SHA(ω)
143
+
144
+ Physical basis: Once νf ≈ 0 after first SHA, subsequent applications
145
+ cannot reduce it further. The effect is saturated.
146
+
147
+ Due to grammar constraints against consecutive SHA operators, we test
148
+ idempotence by comparing SHA behavior in different sequence contexts.
149
+ The key property: SHA always has the same characteristic effect
150
+ (reduce νf to minimum, preserve EPI).
151
+
152
+ Parameters
153
+ ----------
154
+ G : TNFRGraph
155
+ Graph containing the node to validate
156
+ node : NodeId
157
+ Target node identifier
158
+ tolerance : float, optional
159
+ Numerical tolerance for νf comparison (default: 0.05)
160
+
161
+ Returns
162
+ -------
163
+ bool
164
+ True if idempotence holds (consistent SHA behavior)
165
+
166
+ Notes
167
+ -----
168
+ Tests SHA in two different contexts:
169
+ - Context 1: Emission → Coherence → Silence
170
+ - Context 2: Emission → Coherence → Resonance → Silence
171
+
172
+ In both cases, SHA should reduce νf to near-zero and preserve EPI.
173
+ This validates idempotent behavior: SHA effect is consistent and saturated.
174
+
175
+ Examples
176
+ --------
177
+ >>> from tnfr.structural import create_nfr
178
+ >>> from tnfr.operators.algebra import validate_idempotence
179
+ >>> G, node = create_nfr("test", epi=0.65, vf=1.30)
180
+ >>> validate_idempotence(G, node) # doctest: +SKIP
181
+ True
182
+ """
183
+ from ..alias import get_attr
184
+ from ..constants.aliases import ALIAS_VF
185
+ from .definitions import Silence, Emission, Coherence, Resonance
186
+ from ..structural import run_sequence
187
+
188
+ # Test 1: SHA after simple sequence
189
+ G1 = G.copy()
190
+ run_sequence(G1, node, [Emission(), Coherence(), Silence()])
191
+ vf_context1 = float(get_attr(G1.nodes[node], ALIAS_VF, 0.0))
192
+
193
+ # Test 2: SHA after longer sequence (with Resonance added)
194
+ G2 = G.copy()
195
+ run_sequence(G2, node, [Emission(), Coherence(), Resonance(), Silence()])
196
+ vf_context2 = float(get_attr(G2.nodes[node], ALIAS_VF, 0.0))
197
+
198
+ # Idempotence property: SHA behavior is consistent
199
+ # Both νf values should be near-zero (SHA's characteristic effect)
200
+ vf_threshold = 0.15 # SHA should reduce νf below this
201
+ both_minimal = (vf_context1 < vf_threshold) and (vf_context2 < vf_threshold)
202
+
203
+ # Both should be similar (consistent behavior)
204
+ consistent = abs(vf_context1 - vf_context2) < tolerance
205
+
206
+ return both_minimal and consistent
207
+
208
+
209
+ def validate_commutativity_nul(
210
+ G: TNFRGraph,
211
+ node: NodeId,
212
+ tolerance: float = 0.02,
213
+ ) -> bool:
214
+ """Validate that SHA and NUL commute: SHA(NUL(ω)) ≈ NUL(SHA(ω)).
215
+
216
+ Tests the algebraic property that Silence and Contraction can be applied
217
+ in either order with equivalent results.
218
+
219
+ Physical basis: SHA and NUL reduce orthogonal dimensions of state space:
220
+ - SHA reduces νf (reorganization capacity)
221
+ - NUL reduces EPI complexity (structural dimensionality)
222
+
223
+ Since they act on independent dimensions, order doesn't matter for
224
+ final state.
225
+
226
+ Parameters
227
+ ----------
228
+ G : TNFRGraph
229
+ Graph containing the node to validate
230
+ node : NodeId
231
+ Target node identifier
232
+ tolerance : float, optional
233
+ Numerical tolerance for EPI and νf comparison (default: 0.02)
234
+
235
+ Returns
236
+ -------
237
+ bool
238
+ True if commutativity holds within tolerance
239
+
240
+ Notes
241
+ -----
242
+ Tests two paths (both grammar-valid, using Transition as generator):
243
+ 1. Transition → Silence → Contraction
244
+ 2. Transition → Contraction → Silence
245
+
246
+ The property holds if both paths result in equivalent EPI and νf values.
247
+
248
+ Examples
249
+ --------
250
+ >>> from tnfr.structural import create_nfr
251
+ >>> from tnfr.operators.algebra import validate_commutativity_nul
252
+ >>> G, node = create_nfr("test", epi=0.55, vf=1.10)
253
+ >>> validate_commutativity_nul(G, node) # doctest: +SKIP
254
+ True
255
+ """
256
+ from ..alias import get_attr
257
+ from ..constants.aliases import ALIAS_EPI, ALIAS_VF
258
+ from .definitions import Silence, Contraction, Transition
259
+ from ..structural import run_sequence
260
+
261
+ # Path 1: NAV → SHA → NUL (Transition then Silence then Contraction)
262
+ G1 = G.copy()
263
+ run_sequence(G1, node, [Transition(), Silence(), Contraction()])
264
+ epi_sha_nul = float(get_attr(G1.nodes[node], ALIAS_EPI, 0.0))
265
+ vf_sha_nul = float(get_attr(G1.nodes[node], ALIAS_VF, 0.0))
266
+
267
+ # Path 2: NAV → NUL → SHA (Transition then Contraction then Silence)
268
+ G2 = G.copy()
269
+ run_sequence(G2, node, [Transition(), Contraction(), Silence()])
270
+ epi_nul_sha = float(get_attr(G2.nodes[node], ALIAS_EPI, 0.0))
271
+ vf_nul_sha = float(get_attr(G2.nodes[node], ALIAS_VF, 0.0))
272
+
273
+ # Validate commutativity: both paths should produce similar results
274
+ epi_commutes = abs(epi_sha_nul - epi_nul_sha) < tolerance
275
+ vf_commutes = abs(vf_sha_nul - vf_nul_sha) < tolerance
276
+
277
+ return epi_commutes and vf_commutes