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/helpers.py DELETED
@@ -1,198 +0,0 @@
1
- """
2
- helpers.py — TNFR canónica
3
-
4
- Utilidades transversales + cálculo de Índice de sentido (Si).
5
- """
6
- from __future__ import annotations
7
- from typing import Iterable, Dict, Any, Tuple, List
8
- import math
9
- from collections import deque
10
-
11
- try:
12
- import networkx as nx # solo para tipos
13
- except Exception: # pragma: no cover
14
- nx = None # type: ignore
15
-
16
- from constants import DEFAULTS, ALIAS_VF, ALIAS_THETA, ALIAS_DNFR, ALIAS_EPI, ALIAS_SI
17
-
18
- # -------------------------
19
- # Utilidades numéricas
20
- # -------------------------
21
-
22
- def clamp(x: float, a: float, b: float) -> float:
23
- return a if x < a else b if x > b else x
24
-
25
-
26
- def clamp_abs(x: float, m: float) -> float:
27
- m = abs(m)
28
- return clamp(x, -m, m)
29
-
30
-
31
- def clamp01(x: float) -> float:
32
- return clamp(x, 0.0, 1.0)
33
-
34
-
35
- def list_mean(xs: Iterable[float], default: float = 0.0) -> float:
36
- xs = list(xs)
37
- return sum(xs) / len(xs) if xs else default
38
-
39
-
40
- def _wrap_angle(a: float) -> float:
41
- """Envuelve ángulo a (-π, π]."""
42
- pi = math.pi
43
- a = (a + pi) % (2 * pi) - pi
44
- return a
45
-
46
-
47
- def phase_distance(a: float, b: float) -> float:
48
- """Distancia de fase normalizada en [0,1]. 0 = misma fase, 1 = opuesta."""
49
- return abs(_wrap_angle(a - b)) / math.pi
50
-
51
-
52
- # -------------------------
53
- # Acceso a atributos con alias
54
- # -------------------------
55
-
56
- def _get_attr(d: Dict[str, Any], aliases: Iterable[str], default: float = 0.0) -> float:
57
- for k in aliases:
58
- if k in d:
59
- try:
60
- return float(d[k])
61
- except Exception:
62
- continue
63
- return float(default)
64
-
65
- def _set_attr(d, aliases, value: float) -> None:
66
- for k in aliases:
67
- if k in d:
68
- d[k] = float(value)
69
- return
70
- d[next(iter(aliases))] = float(value)
71
-
72
- # -------------------------
73
- # Estadísticos vecinales
74
- # -------------------------
75
-
76
- def media_vecinal(G, n, aliases: Iterable[str], default: float = 0.0) -> float:
77
- vals: List[float] = []
78
- for v in G.neighbors(n):
79
- vals.append(_get_attr(G.nodes[v], aliases, default))
80
- return list_mean(vals, default)
81
-
82
-
83
- def fase_media(G, n) -> float:
84
- """Promedio circular de las fases de los vecinos."""
85
- import math
86
- x = 0.0
87
- y = 0.0
88
- count = 0
89
- for v in G.neighbors(n):
90
- th = _get_attr(G.nodes[v], ALIAS_THETA, 0.0)
91
- x += math.cos(th)
92
- y += math.sin(th)
93
- count += 1
94
- if count == 0:
95
- return _get_attr(G.nodes[n], ALIAS_THETA, 0.0)
96
- return math.atan2(y / max(1, count), x / max(1, count))
97
-
98
-
99
- # -------------------------
100
- # Historial de glifos por nodo
101
- # -------------------------
102
-
103
- def push_glifo(nd: Dict[str, Any], glifo: str, window: int) -> None:
104
- hist = nd.setdefault("hist_glifos", deque(maxlen=window))
105
- hist.append(str(glifo))
106
-
107
-
108
- def reciente_glifo(nd: Dict[str, Any], glifo: str, ventana: int) -> bool:
109
- hist = nd.get("hist_glifos")
110
- if not hist:
111
- return False
112
- last = list(hist)[-ventana:]
113
- return str(glifo) in last
114
-
115
- # -------------------------
116
- # Callbacks Γ(R)
117
- # -------------------------
118
-
119
- def _ensure_callbacks(G):
120
- """Garantiza la estructura de callbacks en G.graph."""
121
- cbs = G.graph.setdefault("callbacks", {
122
- "before_step": [],
123
- "after_step": [],
124
- "on_remesh": [],
125
- })
126
- # normaliza claves por si vienen incompletas
127
- for k in ("before_step", "after_step", "on_remesh"):
128
- cbs.setdefault(k, [])
129
- return cbs
130
-
131
- def register_callback(G, event: str, func):
132
- """Registra un callback en G.graph['callbacks'][event]. Firma: func(G, ctx) -> None"""
133
- if event not in ("before_step", "after_step", "on_remesh"):
134
- raise ValueError(f"Evento desconocido: {event}")
135
- cbs = _ensure_callbacks(G)
136
- cbs[event].append(func)
137
- return func
138
-
139
- def invoke_callbacks(G, event: str, ctx: dict | None = None):
140
- """Invoca todos los callbacks registrados para `event` con el contexto `ctx`."""
141
- cbs = _ensure_callbacks(G).get(event, [])
142
- strict = bool(G.graph.get("CALLBACKS_STRICT", DEFAULTS["CALLBACKS_STRICT"]))
143
- ctx = ctx or {}
144
- for fn in list(cbs):
145
- try:
146
- fn(G, ctx)
147
- except Exception as e:
148
- if strict:
149
- raise
150
- G.graph.setdefault("_callback_errors", []).append({
151
- "event": event, "step": ctx.get("step"), "error": repr(e), "fn": repr(fn)
152
- })
153
-
154
- # -------------------------
155
- # Índice de sentido (Si)
156
- # -------------------------
157
-
158
- def compute_Si(G, *, inplace: bool = True) -> Dict[Any, float]:
159
- """Calcula Si por nodo y lo escribe en G.nodes[n]["Si"].
160
-
161
- Si = α·νf_norm + β·(1 - disp_fase_local) + γ·(1 - |ΔNFR|/max|ΔNFR|)
162
- """
163
- alpha = float(G.graph.get("SI_WEIGHTS", DEFAULTS["SI_WEIGHTS"]).get("alpha", 0.34))
164
- beta = float(G.graph.get("SI_WEIGHTS", DEFAULTS["SI_WEIGHTS"]).get("beta", 0.33))
165
- gamma = float(G.graph.get("SI_WEIGHTS", DEFAULTS["SI_WEIGHTS"]).get("gamma", 0.33))
166
- s = alpha + beta + gamma
167
- if s <= 0:
168
- alpha = beta = gamma = 1/3
169
- else:
170
- alpha, beta, gamma = alpha/s, beta/s, gamma/s
171
-
172
- # Normalización de νf en red
173
- vfs = [abs(_get_attr(G.nodes[n], ALIAS_VF, 0.0)) for n in G.nodes()]
174
- vfmax = max(vfs) if vfs else 1.0
175
- # Normalización de ΔNFR
176
- dnfrs = [abs(_get_attr(G.nodes[n], ALIAS_DNFR, 0.0)) for n in G.nodes()]
177
- dnfrmax = max(dnfrs) if dnfrs else 1.0
178
-
179
- out: Dict[Any, float] = {}
180
- for n in G.nodes():
181
- nd = G.nodes[n]
182
- vf = _get_attr(nd, ALIAS_VF, 0.0)
183
- vf_norm = 0.0 if vfmax == 0 else clamp01(abs(vf)/vfmax)
184
-
185
- # dispersión de fase local
186
- th_i = _get_attr(nd, ALIAS_THETA, 0.0)
187
- th_bar = fase_media(G, n)
188
- disp_fase = phase_distance(th_i, th_bar) # [0,1]
189
-
190
- dnfr = _get_attr(nd, ALIAS_DNFR, 0.0)
191
- dnfr_norm = 0.0 if dnfrmax == 0 else clamp01(abs(dnfr)/dnfrmax)
192
-
193
- Si = alpha*vf_norm + beta*(1.0 - disp_fase) + gamma*(1.0 - dnfr_norm)
194
- Si = clamp01(Si)
195
- out[n] = Si
196
- if inplace:
197
- _set_attr(nd, ALIAS_SI, Si)
198
- return out
tnfr/main.py DELETED
@@ -1,37 +0,0 @@
1
- from __future__ import annotations
2
- import argparse, sys
3
- import networkx as nx
4
- from . import preparar_red, run, __version__
5
-
6
- def main(argv: list[str] | None = None) -> None:
7
- p = argparse.ArgumentParser(
8
- prog="tnfr",
9
- description="TNFR canónica — demo CLI (red Erdős–Rényi + dinámica glífica)",
10
- )
11
- p.add_argument("--version", action="store_true", help="muestra versión y sale")
12
- p.add_argument("--n", type=int, default=30, help="nodos (Erdős–Rényi)")
13
- p.add_argument("--p", type=float, default=0.15, help="probabilidad de arista (Erdős–Rényi)")
14
- p.add_argument("--steps", type=int, default=100, help="pasos a simular")
15
- p.add_argument("--observer", action="store_true", help="adjunta observador estándar")
16
- args = p.parse_args(argv)
17
-
18
- if args.version:
19
- print(__version__)
20
- return
21
-
22
- G = nx.erdos_renyi_graph(args.n, args.p)
23
- preparar_red(G, ATTACH_STD_OBSERVER=bool(args.observer))
24
- run(G, args.steps)
25
-
26
- h = G.graph.get("history", {})
27
- C = h.get("C_steps", [])[-1] if h.get("C_steps") else None
28
- stab = h.get("stable_frac", [])[-1] if h.get("stable_frac") else None
29
- R = h.get("kuramoto_R", [])[-1] if h.get("kuramoto_R") else None
30
-
31
- print("TNFR terminado:")
32
- if C is not None: print(f" C(t) ~ {C:.3f}")
33
- if stab is not None: print(f" estable ~ {stab:.3f}")
34
- if R is not None: print(f" R (Kuramoto) ~ {R:.3f}")
35
-
36
- if __name__ == "__main__":
37
- main(sys.argv[1:])
tnfr/operators.py DELETED
@@ -1,296 +0,0 @@
1
- # operators.py — TNFR canónica (ASCII-safe)
2
- from __future__ import annotations
3
- from typing import Dict, Any, Optional
4
- import math
5
- import random
6
- import hashlib
7
-
8
- from constants import DEFAULTS, ALIAS_VF, ALIAS_THETA, ALIAS_DNFR, ALIAS_EPI, ALIAS_D2EPI
9
- from helpers import _get_attr, _set_attr, clamp, clamp01, list_mean, fase_media, push_glifo, invoke_callbacks
10
-
11
- """
12
- Este módulo implementa:
13
- - Los 13 glifos como operadores locales suaves.
14
- - Un dispatcher `aplicar_glifo` que mapea el nombre del glifo (con apóstrofo tipográfico) a su función.
15
- - RE’MESH de red: `aplicar_remesh_red` y `aplicar_remesh_si_estabilizacion_global`.
16
-
17
- Nota sobre α (alpha) de RE’MESH: se toma por prioridad de
18
- 1) G.graph["GLYPH_FACTORS"]["REMESH_alpha"]
19
- 2) G.graph["REMESH_ALPHA"]
20
- 3) DEFAULTS["REMESH_ALPHA"]
21
- """
22
-
23
- # -------------------------
24
- # Glifos (operadores locales)
25
- # -------------------------
26
-
27
- def op_AL(G, n): # A’L — Emisión
28
- f = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("AL_boost", 0.05))
29
- nd = G.nodes[n]
30
- epi = _get_attr(nd, ALIAS_EPI, 0.0)
31
- _set_attr(nd, ALIAS_EPI, epi + f)
32
-
33
-
34
- def op_EN(G, n): # E’N — Recepción
35
- mix = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("EN_mix", 0.25))
36
- nd = G.nodes[n]
37
- epi = _get_attr(nd, ALIAS_EPI, 0.0)
38
- if G.degree(n) == 0:
39
- return # sin vecinos no hay mezcla
40
- epi_bar = list_mean(_get_attr(G.nodes[v], ALIAS_EPI, epi) for v in G.neighbors(n))
41
- _set_attr(nd, ALIAS_EPI, (1 - mix) * epi + mix * epi_bar)
42
-
43
-
44
- def op_IL(G, n): # I’L — Coherencia (reduce ΔNFR)
45
- factor = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("IL_dnfr_factor", 0.7))
46
- nd = G.nodes[n]
47
- dnfr = _get_attr(nd, ALIAS_DNFR, 0.0)
48
- _set_attr(nd, ALIAS_DNFR, factor * dnfr)
49
-
50
- def op_OZ(G, n): # O’Z — Disonancia (aumenta ΔNFR o añade ruido)
51
- factor = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("OZ_dnfr_factor", 1.3))
52
- nd = G.nodes[n]
53
- dnfr = _get_attr(nd, ALIAS_DNFR, 0.0)
54
- if bool(G.graph.get("OZ_NOISE_MODE", False)):
55
- base_seed = int(G.graph.get("RANDOM_SEED", 0))
56
- step_idx = len(G.graph.get("history", {}).get("C_steps", []))
57
- rnd = random.Random(base_seed + step_idx*1000003 + hash(("OZ", n)) % 1009)
58
- sigma = float(G.graph.get("OZ_SIGMA", 0.1))
59
- noise = sigma * (2.0 * rnd.random() - 1.0)
60
- _set_attr(nd, ALIAS_DNFR, dnfr + noise)
61
- else:
62
- _set_attr(nd, ALIAS_DNFR, factor * dnfr if abs(dnfr) > 1e-9 else 0.1)
63
-
64
- def op_UM(G, n): # U’M — Acoplamiento (empuja fase a la media local)
65
- k = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("UM_theta_push", 0.25))
66
- nd = G.nodes[n]
67
- th = _get_attr(nd, ALIAS_THETA, 0.0)
68
- thL = fase_media(G, n)
69
- d = ((thL - th + math.pi) % (2 * math.pi) - math.pi)
70
- _set_attr(nd, ALIAS_THETA, th + k * d)
71
-
72
-
73
- def op_RA(G, n): # R’A — Resonancia (difusión EPI)
74
- diff = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("RA_epi_diff", 0.15))
75
- nd = G.nodes[n]
76
- epi = _get_attr(nd, ALIAS_EPI, 0.0)
77
- if G.degree(n) == 0:
78
- return
79
- epi_bar = list_mean(_get_attr(G.nodes[v], ALIAS_EPI, epi) for v in G.neighbors(n))
80
- _set_attr(nd, ALIAS_EPI, epi + diff * (epi_bar - epi))
81
-
82
-
83
- def op_SHA(G, n): # SH’A — Silencio (baja νf)
84
- factor = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("SHA_vf_factor", 0.85))
85
- nd = G.nodes[n]
86
- vf = _get_attr(nd, ALIAS_VF, 0.0)
87
- _set_attr(nd, ALIAS_VF, factor * vf)
88
-
89
-
90
- def op_VAL(G, n): # VA’L — Expansión (escala EPI)
91
- s = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("VAL_scale", 1.15))
92
- nd = G.nodes[n]
93
- epi = _get_attr(nd, ALIAS_EPI, 0.0)
94
- _set_attr(nd, ALIAS_EPI, s * epi)
95
-
96
-
97
- def op_NUL(G, n): # NU’L — Contracción (escala EPI)
98
- s = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("NUL_scale", 0.85))
99
- nd = G.nodes[n]
100
- epi = _get_attr(nd, ALIAS_EPI, 0.0)
101
- _set_attr(nd, ALIAS_EPI, s * epi)
102
-
103
-
104
- def op_THOL(G, n): # T’HOL — Autoorganización (inyecta aceleración)
105
- a = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("THOL_accel", 0.10))
106
- nd = G.nodes[n]
107
- d2 = _get_attr(nd, ALIAS_D2EPI, 0.0)
108
- _set_attr(nd, ALIAS_DNFR, _get_attr(nd, ALIAS_DNFR, 0.0) + a * d2)
109
-
110
-
111
- def op_ZHIR(G, n): # Z’HIR — Mutación (desplaza fase)
112
- shift = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("ZHIR_theta_shift", 1.57079632679))
113
- nd = G.nodes[n]
114
- th = _get_attr(nd, ALIAS_THETA, 0.0)
115
- _set_attr(nd, ALIAS_THETA, th + shift)
116
-
117
- def op_NAV(G, n): # NA’V — Transición (jitter suave de ΔNFR)
118
- nd = G.nodes[n]
119
- dnfr = _get_attr(nd, ALIAS_DNFR, 0.0)
120
- j = float(G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"]).get("NAV_jitter", 0.05))
121
- if bool(G.graph.get("NAV_RANDOM", True)):
122
- # jitter uniforme en [-j, j] con semilla reproducible
123
- base_seed = int(G.graph.get("RANDOM_SEED", 0))
124
- # opcional: pequeño offset para evitar misma secuencia en todos los nodos/pasos
125
- step_idx = len(G.graph.get("history", {}).get("C_steps", []))
126
- rnd = random.Random(base_seed + step_idx*1000003 + hash(n) % 1009)
127
- jitter = j * (2.0 * rnd.random() - 1.0)
128
- else:
129
- # comportamiento determinista (compatibilidad previa)
130
- jitter = j * (1 if dnfr >= 0 else -1)
131
- _set_attr(nd, ALIAS_DNFR, dnfr + jitter)
132
-
133
- def op_REMESH(G, n): # RE’MESH — se realiza a escala de red (no-op local con aviso)
134
- # Loguea solo 1 vez por paso para no spamear
135
- step_idx = len(G.graph.get("history", {}).get("C_steps", []))
136
- last_warn = G.graph.get("_remesh_warn_step", None)
137
- if last_warn != step_idx:
138
- msg = "RE’MESH es a escala de red. Usa aplicar_remesh_si_estabilizacion_global(G) o aplicar_remesh_red(G)."
139
- G.graph.setdefault("history", {}).setdefault("events", []).append(("warn", {"step": step_idx, "node": n, "msg": msg}))
140
- G.graph["_remesh_warn_step"] = step_idx
141
- # no cambia estado local
142
- return
143
-
144
- # -------------------------
145
- # Dispatcher
146
- # -------------------------
147
-
148
- _NAME_TO_OP = {
149
- "A’L": op_AL, "E’N": op_EN, "I’L": op_IL, "O’Z": op_OZ, "U’M": op_UM,
150
- "R’A": op_RA, "SH’A": op_SHA, "VA’L": op_VAL, "NU’L": op_NUL,
151
- "T’HOL": op_THOL, "Z’HIR": op_ZHIR, "NA’V": op_NAV, "RE’MESH": op_REMESH,
152
- }
153
-
154
-
155
- def aplicar_glifo(G, n, glifo: str, *, window: Optional[int] = None) -> None:
156
- glifo = str(glifo)
157
- op = _NAME_TO_OP.get(glifo)
158
- if not op:
159
- return
160
- if window is None:
161
- window = int(G.graph.get("GLYPH_HYSTERESIS_WINDOW", DEFAULTS["GLYPH_HYSTERESIS_WINDOW"]))
162
- push_glifo(G.nodes[n], glifo, window)
163
- op(G, n)
164
-
165
-
166
- # -------------------------
167
- # RE’MESH de red (usa _epi_hist capturado en dynamics.step)
168
- # -------------------------
169
-
170
- def _remesh_alpha_info(G):
171
- """Devuelve (alpha, source) con precedencia explícita:
172
- 1) GLYPH_FACTORS["REMESH_alpha"] 2) G.graph["REMESH_ALPHA"] 3) DEFAULTS["REMESH_ALPHA"]"""
173
- gf = G.graph.get("GLYPH_FACTORS", DEFAULTS["GLYPH_FACTORS"])
174
- if "REMESH_alpha" in gf:
175
- return float(gf["REMESH_alpha"]), "GLYPH_FACTORS"
176
- if "REMESH_ALPHA" in G.graph:
177
- return float(G.graph["REMESH_ALPHA"]), "G.graph"
178
- return float(DEFAULTS["REMESH_ALPHA"]), "DEFAULTS"
179
-
180
-
181
- def aplicar_remesh_red(G) -> None:
182
- """
183
- RE’MESH a escala de red usando _epi_hist capturado en dynamics.step.
184
- Loguea meta con alpha/tau/step + topo_hash y checksums/medias de EPI antes/después.
185
- Precedencia de alpha: GLYPH_FACTORS → G.graph → DEFAULTS.
186
- """
187
- tau = int(G.graph.get("REMESH_TAU", DEFAULTS["REMESH_TAU"]))
188
- alpha, alpha_src = _remesh_alpha_info(G)
189
- hist = G.graph.get("_epi_hist", [])
190
- if len(hist) < tau + 1:
191
- return
192
-
193
- past = hist[-(tau + 1)]
194
-
195
- # --- Topología + snapshot EPI (ANTES) ---
196
- try:
197
- n_nodes = G.number_of_nodes()
198
- n_edges = G.number_of_edges()
199
- degs = sorted(d for _, d in G.degree())
200
- topo_str = f"n={n_nodes};m={n_edges};deg=" + ",".join(map(str, degs))
201
- topo_hash = hashlib.sha1(topo_str.encode()).hexdigest()[:12]
202
- except Exception:
203
- topo_hash = None
204
-
205
- def _epi_items():
206
- for node in G.nodes():
207
- yield node, _get_attr(G.nodes[node], ALIAS_EPI, 0.0)
208
-
209
- epi_mean_before = list_mean(v for _, v in _epi_items())
210
- epi_checksum_before = hashlib.sha1(
211
- str(sorted((str(k), round(v, 6)) for k, v in _epi_items())).encode()
212
- ).hexdigest()[:12]
213
-
214
- # --- Mezcla (1-α)·now + α·old ---
215
- for n in G.nodes():
216
- nd = G.nodes[n]
217
- epi_now = _get_attr(nd, ALIAS_EPI, 0.0)
218
- epi_old = float(past.get(n, epi_now))
219
- _set_attr(nd, ALIAS_EPI, (1 - alpha) * epi_now + alpha * epi_old)
220
-
221
- # --- Snapshot EPI (DESPUÉS) ---
222
- epi_mean_after = list_mean(_get_attr(G.nodes[n], ALIAS_EPI, 0.0) for n in G.nodes())
223
- epi_checksum_after = hashlib.sha1(
224
- str(sorted((str(n), round(_get_attr(G.nodes[n], ALIAS_EPI, 0.0), 6)) for n in G.nodes())).encode()
225
- ).hexdigest()[:12]
226
-
227
- # --- Metadatos y logging de evento ---
228
- step_idx = len(G.graph.get("history", {}).get("C_steps", []))
229
- meta = {
230
- "alpha": alpha,
231
- "alpha_source": alpha_src,
232
- "tau": tau,
233
- "step": step_idx,
234
- # firmas
235
- "topo_hash": topo_hash,
236
- "epi_mean_before": float(epi_mean_before),
237
- "epi_mean_after": float(epi_mean_after),
238
- "epi_checksum_before": epi_checksum_before,
239
- "epi_checksum_after": epi_checksum_after,
240
- }
241
-
242
- # Snapshot opcional de métricas recientes
243
- h = G.graph.get("history", {})
244
- if h:
245
- if h.get("stable_frac"): meta["stable_frac_last"] = h["stable_frac"][-1]
246
- if h.get("phase_sync"): meta["phase_sync_last"] = h["phase_sync"][-1]
247
- if h.get("glyph_load_disr"): meta["glyph_disr_last"] = h["glyph_load_disr"][-1]
248
-
249
- G.graph["_REMESH_META"] = meta
250
- if G.graph.get("REMESH_LOG_EVENTS", DEFAULTS["REMESH_LOG_EVENTS"]):
251
- ev = G.graph.setdefault("history", {}).setdefault("remesh_events", [])
252
- ev.append(dict(meta))
253
-
254
- # Callbacks Γ(R)
255
- invoke_callbacks(G, "on_remesh", dict(meta))
256
-
257
- def aplicar_remesh_si_estabilizacion_global(G, pasos_estables_consecutivos: Optional[int] = None) -> None:
258
- # Ventanas y umbrales
259
- w_estab = int(G.graph.get("REMESH_STABILITY_WINDOW", DEFAULTS["REMESH_STABILITY_WINDOW"]))
260
- frac_req = float(G.graph.get("FRACTION_STABLE_REMESH", DEFAULTS["FRACTION_STABLE_REMESH"]))
261
- req_extra = bool(G.graph.get("REMESH_REQUIRE_STABILITY", DEFAULTS["REMESH_REQUIRE_STABILITY"]))
262
- min_sync = float(G.graph.get("REMESH_MIN_PHASE_SYNC", DEFAULTS["REMESH_MIN_PHASE_SYNC"]))
263
- max_disr = float(G.graph.get("REMESH_MAX_GLYPH_DISR", DEFAULTS["REMESH_MAX_GLYPH_DISR"]))
264
-
265
- hist = G.graph.setdefault("history", {"stable_frac": []})
266
- sf = hist.get("stable_frac", [])
267
- if len(sf) < w_estab:
268
- return
269
- # 1) Estabilidad por fracción de nodos estables
270
- win_sf = sf[-w_estab:]
271
- cond_sf = all(v >= frac_req for v in win_sf)
272
- if not cond_sf:
273
- return
274
- # 2) Gating adicional (si está activado)
275
- if req_extra:
276
- # sincronía de fase (mayor mejor)
277
- ps_ok = True
278
- if "phase_sync" in hist and len(hist["phase_sync"]) >= w_estab:
279
- win_ps = hist["phase_sync"][-w_estab:]
280
- ps_ok = (sum(win_ps)/len(win_ps)) >= min_sync
281
- # carga glífica disruptiva (menor mejor)
282
- disr_ok = True
283
- if "glyph_load_disr" in hist and len(hist["glyph_load_disr"]) >= w_estab:
284
- win_disr = hist["glyph_load_disr"][-w_estab:]
285
- disr_ok = (sum(win_disr)/len(win_disr)) <= max_disr
286
- if not (ps_ok and disr_ok):
287
- return
288
- # 3) Cooldown
289
- last = G.graph.get("_last_remesh_step", -10**9)
290
- step_idx = len(sf)
291
- cooldown = int(G.graph.get("REMESH_COOLDOWN_VENTANA", DEFAULTS["REMESH_COOLDOWN_VENTANA"]))
292
- if step_idx - last < cooldown:
293
- return
294
- # 4) Aplicar y registrar
295
- aplicar_remesh_red(G)
296
- G.graph["_last_remesh_step"] = step_idx
@@ -1,35 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: tnfr
3
- Version: 3.0.3
4
- Summary: TNFR canónica: dinámica glífica modular sobre redes.
5
- Author: Fer
6
- License: MIT
7
- Project-URL: Homepage, https://pypi.org/project/tnfr/
8
- Project-URL: Repository, https://github.com/fermga/Teoria-de-la-naturaleza-fractal-resonante-TNFR-
9
- Keywords: TNFR,fractal resonante,resonancia,glifos,networkx,dinámica,coherencia,EPI,Kuramoto
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3 :: Only
12
- Classifier: Programming Language :: Python :: 3.9
13
- Classifier: Programming Language :: Python :: 3.10
14
- Classifier: Programming Language :: Python :: 3.11
15
- Classifier: Programming Language :: Python :: 3.12
16
- Classifier: Programming Language :: Python :: 3.13
17
- Classifier: License :: OSI Approved :: MIT License
18
- Classifier: Operating System :: OS Independent
19
- Classifier: Intended Audience :: Science/Research
20
- Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
- Classifier: Topic :: Scientific/Engineering :: Information Analysis
22
- Requires-Python: >=3.9
23
- Description-Content-Type: text/markdown
24
- License-File: LICENSE.txt
25
- Requires-Dist: networkx>=2.6
26
- Dynamic: license-file
27
-
28
- # tnfr
29
-
30
-
31
- Paquete **tnfr** (canónica). Orquesta dinámica glífica sobre grafos `networkx`.
32
-
33
-
34
- ```bash
35
- pip install tnfr
@@ -1,13 +0,0 @@
1
- tnfr/__init__.py,sha256=TRSH_QpQJthBeGIUFVmxTBNyth5KqRrRfRBnTeGzA40,2012
2
- tnfr/constants.py,sha256=_775sPHussR9vgkWRCLC6dzwgk_1_lLnSlWT8sBWR3U,7677
3
- tnfr/dynamics.py,sha256=7B38c9SVKLVFBrKHeJ1nXbghoRHfDs8Nl9CqUmCcAyI,23260
4
- tnfr/helpers.py,sha256=tZJsDXc8k9HIfg8BA9cVUEFKBoX1Rfnuhurl2Fvxsy0,6017
5
- tnfr/main.py,sha256=TEngteuC9MD7Ec9bNGuCC9ym-2ohbh202-HGArCR4tk,1506
6
- tnfr/observers.py,sha256=MoC-xLJuMP-UYj8cpIVlgSbXDsE1Uj70Zy51PSH3AJY,5192
7
- tnfr/ontosim.py,sha256=U0IeNVF8rFNhnmWWux91xDc0djTDZQkqRRosP6Z7FmE,5485
8
- tnfr/operators.py,sha256=M6ahJL8IuB2y4qiEalge5EufCz0eEbhw-O4xfh3NpwE,12146
9
- tnfr-3.0.3.dist-info/licenses/LICENSE.txt,sha256=xTjBNhy3N8pomFljrCkD1d34SmAEWv8hyJMMOjNMH0M,1071
10
- tnfr-3.0.3.dist-info/METADATA,sha256=aZbWmWTeChR9K_uZSOizMzwggsi5Kv2pQ6Apu58ut8I,1325
11
- tnfr-3.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
12
- tnfr-3.0.3.dist-info/top_level.txt,sha256=Q2HJnvc5Rt2VHwVvyBTnNPT4SfmJWnCj7XUxxEvQa7c,5
13
- tnfr-3.0.3.dist-info/RECORD,,
File without changes