tnfr 4.5.2__py3-none-any.whl → 6.0.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.
Files changed (161) hide show
  1. tnfr/__init__.py +228 -49
  2. tnfr/__init__.pyi +40 -0
  3. tnfr/_compat.py +11 -0
  4. tnfr/_version.py +7 -0
  5. tnfr/_version.pyi +7 -0
  6. tnfr/alias.py +106 -21
  7. tnfr/alias.pyi +140 -0
  8. tnfr/cache.py +666 -512
  9. tnfr/cache.pyi +232 -0
  10. tnfr/callback_utils.py +2 -9
  11. tnfr/callback_utils.pyi +105 -0
  12. tnfr/cli/__init__.py +21 -7
  13. tnfr/cli/__init__.pyi +47 -0
  14. tnfr/cli/arguments.py +42 -20
  15. tnfr/cli/arguments.pyi +33 -0
  16. tnfr/cli/execution.py +54 -20
  17. tnfr/cli/execution.pyi +80 -0
  18. tnfr/cli/utils.py +0 -2
  19. tnfr/cli/utils.pyi +8 -0
  20. tnfr/config/__init__.py +12 -0
  21. tnfr/config/__init__.pyi +8 -0
  22. tnfr/config/constants.py +104 -0
  23. tnfr/config/constants.pyi +12 -0
  24. tnfr/{config.py → config/init.py} +11 -7
  25. tnfr/config/init.pyi +8 -0
  26. tnfr/config/operator_names.py +106 -0
  27. tnfr/config/operator_names.pyi +28 -0
  28. tnfr/config/presets.py +104 -0
  29. tnfr/config/presets.pyi +7 -0
  30. tnfr/constants/__init__.py +78 -24
  31. tnfr/constants/__init__.pyi +104 -0
  32. tnfr/constants/core.py +1 -2
  33. tnfr/constants/core.pyi +17 -0
  34. tnfr/constants/init.pyi +12 -0
  35. tnfr/constants/metric.py +4 -12
  36. tnfr/constants/metric.pyi +19 -0
  37. tnfr/constants_glyphs.py +9 -91
  38. tnfr/constants_glyphs.pyi +12 -0
  39. tnfr/dynamics/__init__.py +112 -634
  40. tnfr/dynamics/__init__.pyi +83 -0
  41. tnfr/dynamics/adaptation.py +201 -0
  42. tnfr/dynamics/aliases.py +22 -0
  43. tnfr/dynamics/coordination.py +343 -0
  44. tnfr/dynamics/dnfr.py +1936 -354
  45. tnfr/dynamics/dnfr.pyi +33 -0
  46. tnfr/dynamics/integrators.py +369 -75
  47. tnfr/dynamics/integrators.pyi +35 -0
  48. tnfr/dynamics/runtime.py +521 -0
  49. tnfr/dynamics/sampling.py +8 -5
  50. tnfr/dynamics/sampling.pyi +7 -0
  51. tnfr/dynamics/selectors.py +680 -0
  52. tnfr/execution.py +56 -41
  53. tnfr/execution.pyi +65 -0
  54. tnfr/flatten.py +7 -7
  55. tnfr/flatten.pyi +28 -0
  56. tnfr/gamma.py +54 -37
  57. tnfr/gamma.pyi +40 -0
  58. tnfr/glyph_history.py +85 -38
  59. tnfr/glyph_history.pyi +53 -0
  60. tnfr/grammar.py +19 -338
  61. tnfr/grammar.pyi +13 -0
  62. tnfr/helpers/__init__.py +110 -30
  63. tnfr/helpers/__init__.pyi +66 -0
  64. tnfr/helpers/numeric.py +1 -0
  65. tnfr/helpers/numeric.pyi +12 -0
  66. tnfr/immutable.py +55 -19
  67. tnfr/immutable.pyi +37 -0
  68. tnfr/initialization.py +12 -10
  69. tnfr/initialization.pyi +73 -0
  70. tnfr/io.py +99 -34
  71. tnfr/io.pyi +11 -0
  72. tnfr/locking.pyi +7 -0
  73. tnfr/metrics/__init__.pyi +20 -0
  74. tnfr/metrics/coherence.py +934 -294
  75. tnfr/metrics/common.py +1 -3
  76. tnfr/metrics/common.pyi +15 -0
  77. tnfr/metrics/core.py +192 -34
  78. tnfr/metrics/core.pyi +13 -0
  79. tnfr/metrics/diagnosis.py +707 -101
  80. tnfr/metrics/diagnosis.pyi +89 -0
  81. tnfr/metrics/export.py +27 -13
  82. tnfr/metrics/glyph_timing.py +218 -38
  83. tnfr/metrics/reporting.py +22 -18
  84. tnfr/metrics/reporting.pyi +12 -0
  85. tnfr/metrics/sense_index.py +199 -25
  86. tnfr/metrics/sense_index.pyi +9 -0
  87. tnfr/metrics/trig.py +53 -18
  88. tnfr/metrics/trig.pyi +12 -0
  89. tnfr/metrics/trig_cache.py +3 -7
  90. tnfr/metrics/trig_cache.pyi +10 -0
  91. tnfr/node.py +148 -125
  92. tnfr/node.pyi +161 -0
  93. tnfr/observers.py +44 -30
  94. tnfr/observers.pyi +46 -0
  95. tnfr/ontosim.py +14 -13
  96. tnfr/ontosim.pyi +33 -0
  97. tnfr/operators/__init__.py +84 -52
  98. tnfr/operators/__init__.pyi +31 -0
  99. tnfr/operators/definitions.py +181 -0
  100. tnfr/operators/definitions.pyi +92 -0
  101. tnfr/operators/jitter.py +86 -23
  102. tnfr/operators/jitter.pyi +11 -0
  103. tnfr/operators/registry.py +80 -0
  104. tnfr/operators/registry.pyi +15 -0
  105. tnfr/operators/remesh.py +141 -57
  106. tnfr/presets.py +9 -54
  107. tnfr/presets.pyi +7 -0
  108. tnfr/py.typed +0 -0
  109. tnfr/rng.py +259 -73
  110. tnfr/rng.pyi +14 -0
  111. tnfr/selector.py +24 -17
  112. tnfr/selector.pyi +19 -0
  113. tnfr/sense.py +55 -43
  114. tnfr/sense.pyi +30 -0
  115. tnfr/structural.py +44 -267
  116. tnfr/structural.pyi +46 -0
  117. tnfr/telemetry/__init__.py +13 -0
  118. tnfr/telemetry/verbosity.py +37 -0
  119. tnfr/tokens.py +3 -2
  120. tnfr/tokens.pyi +41 -0
  121. tnfr/trace.py +272 -82
  122. tnfr/trace.pyi +68 -0
  123. tnfr/types.py +345 -6
  124. tnfr/types.pyi +145 -0
  125. tnfr/utils/__init__.py +158 -0
  126. tnfr/utils/__init__.pyi +133 -0
  127. tnfr/utils/cache.py +755 -0
  128. tnfr/utils/cache.pyi +156 -0
  129. tnfr/{collections_utils.py → utils/data.py} +57 -90
  130. tnfr/utils/data.pyi +73 -0
  131. tnfr/utils/graph.py +87 -0
  132. tnfr/utils/graph.pyi +10 -0
  133. tnfr/utils/init.py +746 -0
  134. tnfr/utils/init.pyi +85 -0
  135. tnfr/{json_utils.py → utils/io.py} +13 -18
  136. tnfr/utils/io.pyi +10 -0
  137. tnfr/utils/validators.py +130 -0
  138. tnfr/utils/validators.pyi +19 -0
  139. tnfr/validation/__init__.py +25 -0
  140. tnfr/validation/__init__.pyi +17 -0
  141. tnfr/validation/compatibility.py +59 -0
  142. tnfr/validation/compatibility.pyi +8 -0
  143. tnfr/validation/grammar.py +149 -0
  144. tnfr/validation/grammar.pyi +11 -0
  145. tnfr/validation/rules.py +194 -0
  146. tnfr/validation/rules.pyi +18 -0
  147. tnfr/validation/syntax.py +151 -0
  148. tnfr/validation/syntax.pyi +7 -0
  149. tnfr-6.0.0.dist-info/METADATA +135 -0
  150. tnfr-6.0.0.dist-info/RECORD +157 -0
  151. tnfr/graph_utils.py +0 -84
  152. tnfr/import_utils.py +0 -228
  153. tnfr/logging_utils.py +0 -116
  154. tnfr/validators.py +0 -84
  155. tnfr/value_utils.py +0 -59
  156. tnfr-4.5.2.dist-info/METADATA +0 -379
  157. tnfr-4.5.2.dist-info/RECORD +0 -67
  158. {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/WHEEL +0 -0
  159. {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/entry_points.txt +0 -0
  160. {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/licenses/LICENSE.md +0 -0
  161. {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/top_level.txt +0 -0
tnfr/config/presets.py ADDED
@@ -0,0 +1,104 @@
1
+ """Predefined TNFR configuration sequences.
2
+
3
+ Only the canonical English preset identifiers are recognised.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from ..execution import (
9
+ CANONICAL_PRESET_NAME,
10
+ CANONICAL_PROGRAM_TOKENS,
11
+ block,
12
+ seq,
13
+ wait,
14
+ )
15
+ from ..types import Glyph, PresetTokens
16
+
17
+ __all__ = (
18
+ "get_preset",
19
+ "PREFERRED_PRESET_NAMES",
20
+ "legacy_preset_guidance",
21
+ )
22
+
23
+
24
+ _PRIMARY_PRESETS: dict[str, PresetTokens] = {
25
+ "resonant_bootstrap": seq(
26
+ Glyph.AL,
27
+ Glyph.EN,
28
+ Glyph.IL,
29
+ Glyph.RA,
30
+ Glyph.VAL,
31
+ Glyph.UM,
32
+ wait(3),
33
+ Glyph.SHA,
34
+ ),
35
+ "contained_mutation": seq(
36
+ Glyph.AL,
37
+ Glyph.EN,
38
+ block(Glyph.OZ, Glyph.ZHIR, Glyph.IL, repeat=2),
39
+ Glyph.RA,
40
+ Glyph.SHA,
41
+ ),
42
+ "coupling_exploration": seq(
43
+ Glyph.AL,
44
+ Glyph.EN,
45
+ Glyph.IL,
46
+ Glyph.VAL,
47
+ Glyph.UM,
48
+ block(Glyph.OZ, Glyph.NAV, Glyph.IL, repeat=1),
49
+ Glyph.RA,
50
+ Glyph.SHA,
51
+ ),
52
+ "fractal_expand": seq(
53
+ block(Glyph.THOL, Glyph.VAL, Glyph.UM, repeat=2, close=Glyph.NUL),
54
+ Glyph.RA,
55
+ ),
56
+ "fractal_contract": seq(
57
+ block(Glyph.THOL, Glyph.NUL, Glyph.UM, repeat=2, close=Glyph.SHA),
58
+ Glyph.RA,
59
+ ),
60
+ CANONICAL_PRESET_NAME: list(CANONICAL_PROGRAM_TOKENS),
61
+ }
62
+
63
+ PREFERRED_PRESET_NAMES: tuple[str, ...] = tuple(_PRIMARY_PRESETS.keys())
64
+
65
+ _PRESETS: dict[str, PresetTokens] = {**_PRIMARY_PRESETS}
66
+
67
+
68
+ _LEGACY_PRESET_ALIASES: dict[str, str] = {
69
+ "arranque_resonante": "resonant_bootstrap",
70
+ "mutacion_contenida": "contained_mutation",
71
+ "exploracion_acople": "coupling_exploration",
72
+ "ejemplo_canonico": CANONICAL_PRESET_NAME,
73
+ }
74
+
75
+
76
+ def legacy_preset_guidance(name: str) -> str | None:
77
+ """Return CLI guidance for historical preset aliases.
78
+
79
+ Parameters
80
+ ----------
81
+ name:
82
+ Identifier received from the CLI.
83
+
84
+ Returns
85
+ -------
86
+ str | None
87
+ A human readable guidance string when ``name`` matches a removed
88
+ alias. ``None`` when no dedicated guidance is available.
89
+ """
90
+
91
+ canonical = _LEGACY_PRESET_ALIASES.get(name)
92
+ if canonical is None:
93
+ return None
94
+ return (
95
+ f"Legacy preset identifier '{name}' was removed in TNFR 9.0. "
96
+ f"Use '{canonical}' instead."
97
+ )
98
+
99
+
100
+ def get_preset(name: str) -> PresetTokens:
101
+ try:
102
+ return _PRESETS[name]
103
+ except KeyError:
104
+ raise KeyError(f"Preset not found: {name}") from None
@@ -0,0 +1,7 @@
1
+ from typing import Any
2
+
3
+ __all__: Any
4
+
5
+ def __getattr__(name: str) -> Any: ...
6
+
7
+ get_preset: Any
@@ -2,10 +2,10 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, Callable
6
- from collections.abc import Mapping
7
5
  import copy
6
+ from collections.abc import Mapping
8
7
  from types import MappingProxyType
8
+ from typing import Callable, TypeVar, cast
9
9
 
10
10
  from .core import CORE_DEFAULTS, REMESH_DEFAULTS
11
11
  from .init import INIT_DEFAULTS
@@ -20,14 +20,51 @@ from .metric import (
20
20
  )
21
21
 
22
22
  from ..immutable import _is_immutable
23
+ from ..types import GraphLike, TNFRConfigValue
24
+
25
+ T = TypeVar("T")
26
+
27
+ STATE_STABLE = "stable"
28
+ STATE_TRANSITION = "transition"
29
+ STATE_DISSONANT = "dissonant"
30
+
31
+ CANONICAL_STATE_TOKENS = frozenset(
32
+ {STATE_STABLE, STATE_TRANSITION, STATE_DISSONANT}
33
+ )
34
+
35
+ def normalise_state_token(token: str) -> str:
36
+ """Return the canonical English token for ``token``.
37
+
38
+ The helper now enforces the English identifiers exclusively. Values that
39
+ do not match the canonical set raise :class:`ValueError` so callers can
40
+ surface explicit migration errors when legacy payloads are encountered.
41
+ """
42
+
43
+ if not isinstance(token, str):
44
+ raise TypeError("state token must be a string")
45
+
46
+ stripped = token.strip()
47
+ lowered = stripped.lower()
48
+
49
+ if stripped in CANONICAL_STATE_TOKENS:
50
+ return stripped
51
+
52
+ if lowered in CANONICAL_STATE_TOKENS:
53
+ return lowered
54
+
55
+ raise ValueError(
56
+ "state token must be one of 'stable', 'transition', or 'dissonant'"
57
+ )
23
58
 
24
59
  try: # pragma: no cover - optional dependency
25
- from ..cache import ensure_node_offset_map
60
+ from ..utils import ensure_node_offset_map as _ensure_node_offset_map
26
61
  except ImportError: # noqa: BLE001 - allow any import error
27
- ensure_node_offset_map = None
62
+ _ensure_node_offset_map = None
63
+
64
+ ensure_node_offset_map: Callable[[GraphLike], None] | None = _ensure_node_offset_map
28
65
 
29
- # Secciones individuales exportadas
30
- DEFAULT_SECTIONS: Mapping[str, Mapping[str, Any]] = MappingProxyType(
66
+ # Exported sections
67
+ DEFAULT_SECTIONS: Mapping[str, Mapping[str, TNFRConfigValue]] = MappingProxyType(
31
68
  {
32
69
  "core": CORE_DEFAULTS,
33
70
  "init": INIT_DEFAULTS,
@@ -36,21 +73,23 @@ DEFAULT_SECTIONS: Mapping[str, Mapping[str, Any]] = MappingProxyType(
36
73
  }
37
74
  )
38
75
 
39
- # Diccionario combinado exportado
40
- # Unimos los diccionarios en orden de menor a mayor prioridad para que los
41
- # valores de ``METRIC_DEFAULTS`` sobrescriban al resto, como hacía
42
- # ``ChainMap``.
43
- DEFAULTS: Mapping[str, Any] = MappingProxyType(
76
+ # Combined exported dictionary
77
+ # Merge the dictionaries from lowest to highest priority so that
78
+ # ``METRIC_DEFAULTS`` overrides the rest, mirroring the previous ``ChainMap``
79
+ # behaviour.
80
+ DEFAULTS: Mapping[str, TNFRConfigValue] = MappingProxyType(
44
81
  CORE_DEFAULTS | INIT_DEFAULTS | REMESH_DEFAULTS | METRIC_DEFAULTS
45
82
  )
46
83
 
47
84
  # -------------------------
48
- # Utilidades
85
+ # Utilities
49
86
  # -------------------------
50
87
 
51
88
 
52
89
  def inject_defaults(
53
- G, defaults: Mapping[str, Any] = DEFAULTS, override: bool = False
90
+ G: GraphLike,
91
+ defaults: Mapping[str, TNFRConfigValue] = DEFAULTS,
92
+ override: bool = False,
54
93
  ) -> None:
55
94
  """Inject ``defaults`` into ``G.graph``.
56
95
 
@@ -63,13 +102,17 @@ def inject_defaults(
63
102
  G.graph.setdefault("_tnfr_defaults_attached", False)
64
103
  for k, v in defaults.items():
65
104
  if override or k not in G.graph:
66
- G.graph[k] = v if _is_immutable(v) else copy.deepcopy(v)
105
+ G.graph[k] = (
106
+ v
107
+ if _is_immutable(v)
108
+ else cast(TNFRConfigValue, copy.deepcopy(v))
109
+ )
67
110
  G.graph["_tnfr_defaults_attached"] = True
68
111
  if ensure_node_offset_map is not None:
69
112
  ensure_node_offset_map(G)
70
113
 
71
114
 
72
- def merge_overrides(G, **overrides) -> None:
115
+ def merge_overrides(G: GraphLike, **overrides: TNFRConfigValue) -> None:
73
116
  """Apply specific changes to ``G.graph``.
74
117
 
75
118
  Non-immutable values are deep-copied to avoid shared state with
@@ -77,20 +120,26 @@ def merge_overrides(G, **overrides) -> None:
77
120
  """
78
121
  for key, value in overrides.items():
79
122
  if key not in DEFAULTS:
80
- raise KeyError(f"Parámetro desconocido: '{key}'")
81
- G.graph[key] = value if _is_immutable(value) else copy.deepcopy(value)
123
+ raise KeyError(f"Unknown parameter: '{key}'")
124
+ G.graph[key] = (
125
+ value
126
+ if _is_immutable(value)
127
+ else cast(TNFRConfigValue, copy.deepcopy(value))
128
+ )
82
129
 
83
130
 
84
- def get_param(G, key: str):
131
+ def get_param(G: GraphLike, key: str) -> TNFRConfigValue:
85
132
  """Retrieve a parameter from ``G.graph`` or fall back to defaults."""
86
133
  if key in G.graph:
87
134
  return G.graph[key]
88
135
  if key not in DEFAULTS:
89
- raise KeyError(f"Parámetro desconocido: '{key}'")
136
+ raise KeyError(f"Unknown parameter: '{key}'")
90
137
  return DEFAULTS[key]
91
138
 
92
139
 
93
- def get_graph_param(G, key: str, cast: Callable[[Any], Any] = float):
140
+ def get_graph_param(
141
+ G: GraphLike, key: str, cast: Callable[[object], T] = float
142
+ ) -> T | None:
94
143
  """Return ``key`` from ``G.graph`` applying ``cast``.
95
144
 
96
145
  The ``cast`` argument must be a function (e.g. ``float``, ``int``,
@@ -101,14 +150,14 @@ def get_graph_param(G, key: str, cast: Callable[[Any], Any] = float):
101
150
  return None if val is None else cast(val)
102
151
 
103
152
 
104
- # Claves canónicas con nombres ASCII
153
+ # Canonical keys with ASCII spellings
105
154
  VF_KEY = "νf"
106
- THETA_KEY = "θ"
155
+ THETA_KEY = "theta"
107
156
 
108
- # Mapa de aliases para atributos nodales
157
+ # Alias map for node attributes
109
158
  ALIASES: dict[str, tuple[str, ...]] = {
110
159
  "VF": (VF_KEY, "nu_f", "nu-f", "nu", "freq", "frequency"),
111
- "THETA": (THETA_KEY, "theta", "fase", "phi", "phase"),
160
+ "THETA": (THETA_KEY, "phase"),
112
161
  "DNFR": ("ΔNFR", "delta_nfr", "dnfr"),
113
162
  "EPI": ("EPI", "psi", "PSI", "value"),
114
163
  "EPI_KIND": ("EPI_kind", "epi_kind", "source_glyph"),
@@ -171,4 +220,9 @@ __all__ = (
171
220
  "dVF_PRIMARY",
172
221
  "D2VF_PRIMARY",
173
222
  "dSI_PRIMARY",
223
+ "STATE_STABLE",
224
+ "STATE_TRANSITION",
225
+ "STATE_DISSONANT",
226
+ "CANONICAL_STATE_TOKENS",
227
+ "normalise_state_token",
174
228
  )
@@ -0,0 +1,104 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Callable, TypeVar
5
+
6
+ from .core import CORE_DEFAULTS as CORE_DEFAULTS, REMESH_DEFAULTS as REMESH_DEFAULTS
7
+ from .init import INIT_DEFAULTS as INIT_DEFAULTS
8
+ from .metric import (
9
+ COHERENCE as COHERENCE,
10
+ DIAGNOSIS as DIAGNOSIS,
11
+ GRAMMAR_CANON as GRAMMAR_CANON,
12
+ METRICS as METRICS,
13
+ METRIC_DEFAULTS as METRIC_DEFAULTS,
14
+ SIGMA as SIGMA,
15
+ TRACE as TRACE,
16
+ )
17
+ from ..types import GraphLike, TNFRConfigValue
18
+
19
+ T = TypeVar("T")
20
+
21
+ __all__ = (
22
+ "CORE_DEFAULTS",
23
+ "INIT_DEFAULTS",
24
+ "REMESH_DEFAULTS",
25
+ "METRIC_DEFAULTS",
26
+ "SIGMA",
27
+ "TRACE",
28
+ "METRICS",
29
+ "GRAMMAR_CANON",
30
+ "COHERENCE",
31
+ "DIAGNOSIS",
32
+ "DEFAULTS",
33
+ "DEFAULT_SECTIONS",
34
+ "ALIASES",
35
+ "inject_defaults",
36
+ "merge_overrides",
37
+ "get_param",
38
+ "get_graph_param",
39
+ "get_aliases",
40
+ "VF_KEY",
41
+ "THETA_KEY",
42
+ "VF_PRIMARY",
43
+ "THETA_PRIMARY",
44
+ "DNFR_PRIMARY",
45
+ "EPI_PRIMARY",
46
+ "EPI_KIND_PRIMARY",
47
+ "SI_PRIMARY",
48
+ "dEPI_PRIMARY",
49
+ "D2EPI_PRIMARY",
50
+ "dVF_PRIMARY",
51
+ "D2VF_PRIMARY",
52
+ "dSI_PRIMARY",
53
+ "STATE_STABLE",
54
+ "STATE_TRANSITION",
55
+ "STATE_DISSONANT",
56
+ "CANONICAL_STATE_TOKENS",
57
+ "normalise_state_token",
58
+ )
59
+
60
+ ensure_node_offset_map: Callable[[GraphLike], None] | None
61
+ DEFAULT_SECTIONS: Mapping[str, Mapping[str, TNFRConfigValue]]
62
+ DEFAULTS: Mapping[str, TNFRConfigValue]
63
+ ALIASES: dict[str, tuple[str, ...]]
64
+ VF_KEY: str
65
+ THETA_KEY: str
66
+ VF_PRIMARY: str
67
+ THETA_PRIMARY: str
68
+ DNFR_PRIMARY: str
69
+ EPI_PRIMARY: str
70
+ EPI_KIND_PRIMARY: str
71
+ SI_PRIMARY: str
72
+ dEPI_PRIMARY: str
73
+ D2EPI_PRIMARY: str
74
+ dVF_PRIMARY: str
75
+ D2VF_PRIMARY: str
76
+ dSI_PRIMARY: str
77
+ STATE_STABLE: str
78
+ STATE_TRANSITION: str
79
+ STATE_DISSONANT: str
80
+ CANONICAL_STATE_TOKENS: frozenset[str]
81
+
82
+
83
+ def inject_defaults(
84
+ G: GraphLike,
85
+ defaults: Mapping[str, TNFRConfigValue] = ...,
86
+ override: bool = ...,
87
+ ) -> None: ...
88
+
89
+
90
+ def merge_overrides(G: GraphLike, **overrides: TNFRConfigValue) -> None: ...
91
+
92
+
93
+ def get_param(G: GraphLike, key: str) -> TNFRConfigValue: ...
94
+
95
+
96
+ def get_graph_param(
97
+ G: GraphLike, key: str, cast: Callable[[object], T] = ...
98
+ ) -> T | None: ...
99
+
100
+
101
+ def get_aliases(key: str) -> tuple[str, ...]: ...
102
+
103
+
104
+ def normalise_state_token(token: str) -> str: ...
tnfr/constants/core.py CHANGED
@@ -134,7 +134,7 @@ class RemeshDefaults:
134
134
  EPS_DNFR_STABLE: float = 1e-3
135
135
  EPS_DEPI_STABLE: float = 1e-3
136
136
  FRACTION_STABLE_REMESH: float = 0.80
137
- REMESH_COOLDOWN_VENTANA: int = 20
137
+ REMESH_COOLDOWN_WINDOW: int = 20
138
138
  REMESH_COOLDOWN_TS: float = 0.0
139
139
  REMESH_REQUIRE_STABILITY: bool = True
140
140
  REMESH_STABILITY_WINDOW: int = 25
@@ -151,7 +151,6 @@ class RemeshDefaults:
151
151
  REMESH_ALPHA: float = 0.5
152
152
  REMESH_ALPHA_HARD: bool = False
153
153
 
154
-
155
154
  _core_defaults = asdict(CoreDefaults())
156
155
  _remesh_defaults = asdict(RemeshDefaults())
157
156
 
@@ -0,0 +1,17 @@
1
+ from typing import Any
2
+
3
+ __all__: Any
4
+
5
+ def __getattr__(name: str) -> Any: ...
6
+
7
+ CORE_DEFAULTS: Any
8
+ CoreDefaults: Any
9
+ Mapping: Any
10
+ MappingProxyType: Any
11
+ REMESH_DEFAULTS: Any
12
+ RemeshDefaults: Any
13
+ SELECTOR_THRESHOLD_DEFAULTS: Any
14
+ annotations: Any
15
+ asdict: Any
16
+ dataclass: Any
17
+ field: Any
@@ -0,0 +1,12 @@
1
+ from typing import Any
2
+
3
+ __all__: Any
4
+
5
+ def __getattr__(name: str) -> Any: ...
6
+
7
+ INIT_DEFAULTS: Any
8
+ InitDefaults: Any
9
+ annotations: Any
10
+ asdict: Any
11
+ dataclass: Any
12
+ math: Any
tnfr/constants/metric.py CHANGED
@@ -35,18 +35,7 @@ class MetricDefaults:
35
35
  TRACE: dict[str, Any] = field(
36
36
  default_factory=lambda: {
37
37
  "enabled": True,
38
- "capture": [
39
- "gamma",
40
- "grammar",
41
- "selector",
42
- "dnfr_weights",
43
- "si_weights",
44
- "callbacks",
45
- "thol_open_nodes",
46
- "sigma",
47
- "kuramoto",
48
- "glyph_counts",
49
- ],
38
+ "verbosity": "debug",
50
39
  "history_key": "trace_meta",
51
40
  }
52
41
  )
@@ -55,6 +44,8 @@ class MetricDefaults:
55
44
  "enabled": True,
56
45
  "save_by_node": True,
57
46
  "normalize_series": False,
47
+ "n_jobs": 1,
48
+ "verbosity": "debug",
58
49
  }
59
50
  )
60
51
  GRAMMAR_CANON: dict[str, Any] = field(
@@ -76,6 +67,7 @@ class MetricDefaults:
76
67
  "self_on_diag": True,
77
68
  "store_mode": "sparse",
78
69
  "threshold": 0.0,
70
+ "n_jobs": 1,
79
71
  "history_key": "W_sparse",
80
72
  "Wi_history_key": "W_i",
81
73
  "stats_history_key": "W_stats",
@@ -0,0 +1,19 @@
1
+ from typing import Any
2
+
3
+ __all__: Any
4
+
5
+ def __getattr__(name: str) -> Any: ...
6
+
7
+ COHERENCE: Any
8
+ DIAGNOSIS: Any
9
+ GRAMMAR_CANON: Any
10
+ METRICS: Any
11
+ METRIC_DEFAULTS: Any
12
+ MappingProxyType: Any
13
+ MetricDefaults: Any
14
+ SIGMA: Any
15
+ TRACE: Any
16
+ annotations: Any
17
+ asdict: Any
18
+ dataclass: Any
19
+ field: Any
tnfr/constants_glyphs.py CHANGED
@@ -1,98 +1,16 @@
1
- """Default glyphs."""
1
+ """Backward compatibility shim for glyph constants."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- import math
6
- from types import MappingProxyType
7
- from typing import Mapping
5
+ import warnings
8
6
 
9
- from .types import Glyph
7
+ from .config.constants import * # noqa: F401,F403 - re-export legacy API
8
+ from .config.constants import __all__ as _CONFIG_ALL
10
9
 
11
- # -------------------------
12
- # Orden canónico y clasificaciones funcionales
13
- # -------------------------
14
-
15
- GLYPHS_CANONICAL: tuple[str, ...] = (
16
- Glyph.AL.value, # 0
17
- Glyph.EN.value, # 1
18
- Glyph.IL.value, # 2
19
- Glyph.OZ.value, # 3
20
- Glyph.UM.value, # 4
21
- Glyph.RA.value, # 5
22
- Glyph.SHA.value, # 6
23
- Glyph.VAL.value, # 7
24
- Glyph.NUL.value, # 8
25
- Glyph.THOL.value, # 9
26
- Glyph.ZHIR.value, # 10
27
- Glyph.NAV.value, # 11
28
- Glyph.REMESH.value, # 12
10
+ warnings.warn(
11
+ "'tnfr.constants_glyphs' is deprecated; use 'tnfr.config.constants' instead",
12
+ DeprecationWarning,
13
+ stacklevel=2,
29
14
  )
30
15
 
31
- GLYPHS_CANONICAL_SET: frozenset[str] = frozenset(GLYPHS_CANONICAL)
32
-
33
- ESTABILIZADORES = (
34
- Glyph.IL.value,
35
- Glyph.RA.value,
36
- Glyph.UM.value,
37
- Glyph.SHA.value,
38
- )
39
-
40
- DISRUPTIVOS = (
41
- Glyph.OZ.value,
42
- Glyph.ZHIR.value,
43
- Glyph.NAV.value,
44
- Glyph.THOL.value,
45
- )
46
-
47
- # Mapa general de agrupaciones glíficas para referencia cruzada.
48
- GLYPH_GROUPS: Mapping[str, tuple[str, ...]] = MappingProxyType(
49
- {
50
- "estabilizadores": ESTABILIZADORES,
51
- "disruptivos": DISRUPTIVOS,
52
- # Grupos auxiliares para métricas morfosintácticas
53
- "ID": (Glyph.OZ.value,),
54
- "CM": (Glyph.ZHIR.value, Glyph.NAV.value),
55
- "NE": (Glyph.IL.value, Glyph.THOL.value),
56
- "PP_num": (Glyph.SHA.value,),
57
- "PP_den": (Glyph.REMESH.value,),
58
- }
59
- )
60
-
61
- # -------------------------
62
- # Mapa de ángulos glíficos
63
- # -------------------------
64
-
65
- # Ángulos canónicos para todos los glyphs reconocidos. Se calculan a partir
66
- # del orden canónico y reglas de orientación para las categorías
67
- # "estabilizadores" y "disruptivos".
68
-
69
-
70
- def _build_angle_map() -> dict[str, float]:
71
- """Construir el mapa de ángulos en el plano σ."""
72
- step = 2 * math.pi / len(GLYPHS_CANONICAL)
73
- canonical = {g: i * step for i, g in enumerate(GLYPHS_CANONICAL)}
74
- angles = dict(canonical)
75
-
76
- # Reglas específicas de orientación
77
- for idx, g in enumerate(ESTABILIZADORES):
78
- angles[g] = idx * math.pi / 4
79
- for idx, g in enumerate(DISRUPTIVOS):
80
- angles[g] = math.pi + idx * math.pi / 4
81
-
82
- # Excepciones manuales
83
- angles[Glyph.VAL.value] = canonical[Glyph.RA.value]
84
- angles[Glyph.NUL.value] = canonical[Glyph.ZHIR.value]
85
- angles[Glyph.AL.value] = 0.0
86
- return angles
87
-
88
-
89
- ANGLE_MAP: Mapping[str, float] = MappingProxyType(_build_angle_map())
90
-
91
- __all__ = (
92
- "GLYPHS_CANONICAL",
93
- "GLYPHS_CANONICAL_SET",
94
- "ESTABILIZADORES",
95
- "DISRUPTIVOS",
96
- "GLYPH_GROUPS",
97
- "ANGLE_MAP",
98
- )
16
+ __all__ = _CONFIG_ALL
@@ -0,0 +1,12 @@
1
+ from typing import Any
2
+
3
+ __all__: Any
4
+
5
+ def __getattr__(name: str) -> Any: ...
6
+
7
+ ANGLE_MAP: Any
8
+ DISRUPTORS: Any
9
+ STABILIZERS: Any
10
+ GLYPHS_CANONICAL: Any
11
+ GLYPHS_CANONICAL_SET: Any
12
+ GLYPH_GROUPS: Any