tnfr 4.5.1__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 (170) hide show
  1. tnfr/__init__.py +270 -90
  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 +631 -0
  7. tnfr/alias.pyi +140 -0
  8. tnfr/cache.py +732 -0
  9. tnfr/cache.pyi +232 -0
  10. tnfr/callback_utils.py +381 -0
  11. tnfr/callback_utils.pyi +105 -0
  12. tnfr/cli/__init__.py +89 -0
  13. tnfr/cli/__init__.pyi +47 -0
  14. tnfr/cli/arguments.py +199 -0
  15. tnfr/cli/arguments.pyi +33 -0
  16. tnfr/cli/execution.py +322 -0
  17. tnfr/cli/execution.pyi +80 -0
  18. tnfr/cli/utils.py +34 -0
  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/init.py +36 -0
  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 +228 -0
  31. tnfr/constants/__init__.pyi +104 -0
  32. tnfr/constants/core.py +158 -0
  33. tnfr/constants/core.pyi +17 -0
  34. tnfr/constants/init.py +31 -0
  35. tnfr/constants/init.pyi +12 -0
  36. tnfr/constants/metric.py +102 -0
  37. tnfr/constants/metric.pyi +19 -0
  38. tnfr/constants_glyphs.py +16 -0
  39. tnfr/constants_glyphs.pyi +12 -0
  40. tnfr/dynamics/__init__.py +136 -0
  41. tnfr/dynamics/__init__.pyi +83 -0
  42. tnfr/dynamics/adaptation.py +201 -0
  43. tnfr/dynamics/aliases.py +22 -0
  44. tnfr/dynamics/coordination.py +343 -0
  45. tnfr/dynamics/dnfr.py +2315 -0
  46. tnfr/dynamics/dnfr.pyi +33 -0
  47. tnfr/dynamics/integrators.py +561 -0
  48. tnfr/dynamics/integrators.pyi +35 -0
  49. tnfr/dynamics/runtime.py +521 -0
  50. tnfr/dynamics/sampling.py +34 -0
  51. tnfr/dynamics/sampling.pyi +7 -0
  52. tnfr/dynamics/selectors.py +680 -0
  53. tnfr/execution.py +216 -0
  54. tnfr/execution.pyi +65 -0
  55. tnfr/flatten.py +283 -0
  56. tnfr/flatten.pyi +28 -0
  57. tnfr/gamma.py +320 -89
  58. tnfr/gamma.pyi +40 -0
  59. tnfr/glyph_history.py +337 -0
  60. tnfr/glyph_history.pyi +53 -0
  61. tnfr/grammar.py +23 -153
  62. tnfr/grammar.pyi +13 -0
  63. tnfr/helpers/__init__.py +151 -0
  64. tnfr/helpers/__init__.pyi +66 -0
  65. tnfr/helpers/numeric.py +88 -0
  66. tnfr/helpers/numeric.pyi +12 -0
  67. tnfr/immutable.py +214 -0
  68. tnfr/immutable.pyi +37 -0
  69. tnfr/initialization.py +199 -0
  70. tnfr/initialization.pyi +73 -0
  71. tnfr/io.py +311 -0
  72. tnfr/io.pyi +11 -0
  73. tnfr/locking.py +37 -0
  74. tnfr/locking.pyi +7 -0
  75. tnfr/metrics/__init__.py +41 -0
  76. tnfr/metrics/__init__.pyi +20 -0
  77. tnfr/metrics/coherence.py +1469 -0
  78. tnfr/metrics/common.py +149 -0
  79. tnfr/metrics/common.pyi +15 -0
  80. tnfr/metrics/core.py +259 -0
  81. tnfr/metrics/core.pyi +13 -0
  82. tnfr/metrics/diagnosis.py +840 -0
  83. tnfr/metrics/diagnosis.pyi +89 -0
  84. tnfr/metrics/export.py +151 -0
  85. tnfr/metrics/glyph_timing.py +369 -0
  86. tnfr/metrics/reporting.py +152 -0
  87. tnfr/metrics/reporting.pyi +12 -0
  88. tnfr/metrics/sense_index.py +294 -0
  89. tnfr/metrics/sense_index.pyi +9 -0
  90. tnfr/metrics/trig.py +216 -0
  91. tnfr/metrics/trig.pyi +12 -0
  92. tnfr/metrics/trig_cache.py +105 -0
  93. tnfr/metrics/trig_cache.pyi +10 -0
  94. tnfr/node.py +255 -177
  95. tnfr/node.pyi +161 -0
  96. tnfr/observers.py +154 -150
  97. tnfr/observers.pyi +46 -0
  98. tnfr/ontosim.py +135 -134
  99. tnfr/ontosim.pyi +33 -0
  100. tnfr/operators/__init__.py +452 -0
  101. tnfr/operators/__init__.pyi +31 -0
  102. tnfr/operators/definitions.py +181 -0
  103. tnfr/operators/definitions.pyi +92 -0
  104. tnfr/operators/jitter.py +266 -0
  105. tnfr/operators/jitter.pyi +11 -0
  106. tnfr/operators/registry.py +80 -0
  107. tnfr/operators/registry.pyi +15 -0
  108. tnfr/operators/remesh.py +569 -0
  109. tnfr/presets.py +10 -23
  110. tnfr/presets.pyi +7 -0
  111. tnfr/py.typed +0 -0
  112. tnfr/rng.py +440 -0
  113. tnfr/rng.pyi +14 -0
  114. tnfr/selector.py +217 -0
  115. tnfr/selector.pyi +19 -0
  116. tnfr/sense.py +307 -142
  117. tnfr/sense.pyi +30 -0
  118. tnfr/structural.py +69 -164
  119. tnfr/structural.pyi +46 -0
  120. tnfr/telemetry/__init__.py +13 -0
  121. tnfr/telemetry/verbosity.py +37 -0
  122. tnfr/tokens.py +61 -0
  123. tnfr/tokens.pyi +41 -0
  124. tnfr/trace.py +520 -95
  125. tnfr/trace.pyi +68 -0
  126. tnfr/types.py +382 -17
  127. tnfr/types.pyi +145 -0
  128. tnfr/utils/__init__.py +158 -0
  129. tnfr/utils/__init__.pyi +133 -0
  130. tnfr/utils/cache.py +755 -0
  131. tnfr/utils/cache.pyi +156 -0
  132. tnfr/utils/data.py +267 -0
  133. tnfr/utils/data.pyi +73 -0
  134. tnfr/utils/graph.py +87 -0
  135. tnfr/utils/graph.pyi +10 -0
  136. tnfr/utils/init.py +746 -0
  137. tnfr/utils/init.pyi +85 -0
  138. tnfr/utils/io.py +157 -0
  139. tnfr/utils/io.pyi +10 -0
  140. tnfr/utils/validators.py +130 -0
  141. tnfr/utils/validators.pyi +19 -0
  142. tnfr/validation/__init__.py +25 -0
  143. tnfr/validation/__init__.pyi +17 -0
  144. tnfr/validation/compatibility.py +59 -0
  145. tnfr/validation/compatibility.pyi +8 -0
  146. tnfr/validation/grammar.py +149 -0
  147. tnfr/validation/grammar.pyi +11 -0
  148. tnfr/validation/rules.py +194 -0
  149. tnfr/validation/rules.pyi +18 -0
  150. tnfr/validation/syntax.py +151 -0
  151. tnfr/validation/syntax.pyi +7 -0
  152. tnfr-6.0.0.dist-info/METADATA +135 -0
  153. tnfr-6.0.0.dist-info/RECORD +157 -0
  154. tnfr/cli.py +0 -322
  155. tnfr/config.py +0 -41
  156. tnfr/constants.py +0 -277
  157. tnfr/dynamics.py +0 -814
  158. tnfr/helpers.py +0 -264
  159. tnfr/main.py +0 -47
  160. tnfr/metrics.py +0 -597
  161. tnfr/operators.py +0 -525
  162. tnfr/program.py +0 -176
  163. tnfr/scenarios.py +0 -34
  164. tnfr/validators.py +0 -38
  165. tnfr-4.5.1.dist-info/METADATA +0 -221
  166. tnfr-4.5.1.dist-info/RECORD +0 -28
  167. {tnfr-4.5.1.dist-info → tnfr-6.0.0.dist-info}/WHEEL +0 -0
  168. {tnfr-4.5.1.dist-info → tnfr-6.0.0.dist-info}/entry_points.txt +0 -0
  169. {tnfr-4.5.1.dist-info → tnfr-6.0.0.dist-info}/licenses/LICENSE.md +0 -0
  170. {tnfr-4.5.1.dist-info → tnfr-6.0.0.dist-info}/top_level.txt +0 -0
tnfr/trace.pyi ADDED
@@ -0,0 +1,68 @@
1
+ from typing import Any, Callable, NamedTuple, TypedDict
2
+ from collections.abc import Iterable, Mapping
3
+
4
+ from .types import TNFRGraph, TraceFieldFn, TraceFieldMap, TraceFieldRegistry
5
+
6
+ __all__: tuple[str, ...]
7
+
8
+ def __getattr__(name: str) -> Any: ...
9
+
10
+
11
+ class CallbackSpec(NamedTuple):
12
+ name: str | None
13
+ func: Callable[..., Any]
14
+
15
+
16
+ class TraceMetadata(TypedDict, total=False):
17
+ gamma: Mapping[str, Any]
18
+ grammar: Mapping[str, Any]
19
+ selector: str | None
20
+ dnfr_weights: Mapping[str, Any]
21
+ si_weights: Mapping[str, Any]
22
+ si_sensitivity: Mapping[str, Any]
23
+ callbacks: Mapping[str, list[str] | None]
24
+ thol_open_nodes: int
25
+ kuramoto: Mapping[str, float]
26
+ sigma: Mapping[str, float]
27
+ glyphs: Mapping[str, int]
28
+
29
+
30
+ class TraceSnapshot(TraceMetadata, total=False):
31
+ t: float
32
+ phase: str
33
+
34
+
35
+ kuramoto_R_psi: Callable[[TNFRGraph], tuple[float, float]]
36
+ TRACE_FIELDS: TraceFieldRegistry
37
+
38
+ def _callback_names(
39
+ callbacks: Mapping[str, CallbackSpec] | Iterable[CallbackSpec],
40
+ ) -> list[str]: ...
41
+
42
+ def mapping_field(G: TNFRGraph, graph_key: str, out_key: str) -> TraceMetadata: ...
43
+
44
+ def _trace_capture(G: TNFRGraph, phase: str, fields: TraceFieldMap) -> None: ...
45
+
46
+ def register_trace_field(phase: str, name: str, func: TraceFieldFn) -> None: ...
47
+
48
+ def gamma_field(G: TNFRGraph) -> TraceMetadata: ...
49
+
50
+ def grammar_field(G: TNFRGraph) -> TraceMetadata: ...
51
+
52
+ def dnfr_weights_field(G: TNFRGraph) -> TraceMetadata: ...
53
+
54
+ def selector_field(G: TNFRGraph) -> TraceMetadata: ...
55
+
56
+ def si_weights_field(G: TNFRGraph) -> TraceMetadata: ...
57
+
58
+ def callbacks_field(G: TNFRGraph) -> TraceMetadata: ...
59
+
60
+ def thol_state_field(G: TNFRGraph) -> TraceMetadata: ...
61
+
62
+ def kuramoto_field(G: TNFRGraph) -> TraceMetadata: ...
63
+
64
+ def sigma_field(G: TNFRGraph) -> TraceMetadata: ...
65
+
66
+ def glyph_counts_field(G: TNFRGraph) -> TraceMetadata: ...
67
+
68
+ def register_trace(G: TNFRGraph) -> None: ...
tnfr/types.py CHANGED
@@ -1,18 +1,383 @@
1
+ """Type definitions and protocols shared across the engine."""
2
+
1
3
  from __future__ import annotations
2
- from dataclasses import dataclass, field
3
- from typing import Dict, Any
4
-
5
-
6
- @dataclass
7
- class NodeState:
8
- EPI: float = 0.0
9
- vf: float = 1.0 # νf
10
- theta: float = 0.0 # θ
11
- Si: float = 0.5
12
- epi_kind: str = ""
13
- extra: Dict[str, Any] = field(default_factory=dict)
14
-
15
- def to_attrs(self) -> Dict[str, Any]:
16
- d = {"EPI": self.EPI, "νf": self.vf, "θ": self.theta, "Si": self.Si, "EPI_kind": self.epi_kind}
17
- d.update(self.extra)
18
- return d
4
+
5
+ from collections.abc import Callable, Hashable, Mapping, MutableMapping, Sequence
6
+ from enum import Enum
7
+ from typing import TYPE_CHECKING, Any, ContextManager, Iterable, Protocol, TypedDict
8
+ from types import SimpleNamespace
9
+
10
+ from ._compat import TypeAlias
11
+
12
+ try: # pragma: no cover - optional dependency for typing only
13
+ import numpy as np
14
+ except Exception: # pragma: no cover - graceful fallback when NumPy is missing
15
+ np = SimpleNamespace(ndarray=Any, float_=float) # type: ignore[assignment]
16
+
17
+ if TYPE_CHECKING: # pragma: no cover - import-time typing hook
18
+ try:
19
+ import numpy.typing as npt
20
+ except Exception: # pragma: no cover - fallback when NumPy typing is missing
21
+ npt = SimpleNamespace(NDArray=Any) # type: ignore[assignment]
22
+ else: # pragma: no cover - runtime fallback without numpy.typing
23
+ npt = SimpleNamespace(NDArray=Any) # type: ignore[assignment]
24
+
25
+ __all__ = (
26
+ "TNFRGraph",
27
+ "Graph",
28
+ "NodeId",
29
+ "Node",
30
+ "GammaSpec",
31
+ "EPIValue",
32
+ "DeltaNFR",
33
+ "SecondDerivativeEPI",
34
+ "Phase",
35
+ "StructuralFrequency",
36
+ "SenseIndex",
37
+ "CouplingWeight",
38
+ "CoherenceMetric",
39
+ "DeltaNFRHook",
40
+ "GraphLike",
41
+ "IntegratorProtocol",
42
+ "Glyph",
43
+ "GlyphLoadDistribution",
44
+ "GlyphSelector",
45
+ "SelectorPreselectionMetrics",
46
+ "SelectorPreselectionChoices",
47
+ "SelectorPreselectionPayload",
48
+ "SelectorMetrics",
49
+ "SelectorNorms",
50
+ "SelectorThresholds",
51
+ "SelectorWeights",
52
+ "TraceCallback",
53
+ "TraceFieldFn",
54
+ "TraceFieldMap",
55
+ "TraceFieldRegistry",
56
+ "HistoryState",
57
+ "DiagnosisNodeData",
58
+ "DiagnosisSharedState",
59
+ "DiagnosisPayload",
60
+ "DiagnosisResult",
61
+ "DiagnosisPayloadChunk",
62
+ "DiagnosisResultList",
63
+ "DnfrCacheVectors",
64
+ "DnfrVectorMap",
65
+ "NeighborStats",
66
+ "TimingContext",
67
+ "PresetTokens",
68
+ "ProgramTokens",
69
+ "ArgSpec",
70
+ "TNFRConfigValue",
71
+ "SigmaVector",
72
+ "FloatArray",
73
+ "FloatMatrix",
74
+ "NodeInitAttrMap",
75
+ )
76
+
77
+
78
+ if TYPE_CHECKING: # pragma: no cover - import-time typing hook
79
+ import networkx as nx
80
+ from .trace import TraceMetadata
81
+ from .glyph_history import HistoryDict as _HistoryDict
82
+ from .tokens import Token as _Token
83
+
84
+ TNFRGraph: TypeAlias = nx.Graph
85
+ else: # pragma: no cover - runtime fallback without networkx
86
+ TNFRGraph: TypeAlias = Any
87
+ _HistoryDict = Any # type: ignore[assignment]
88
+ _Token = Any # type: ignore[assignment]
89
+ #: Graph container storing TNFR nodes, edges and their coherence telemetry.
90
+
91
+ if TYPE_CHECKING:
92
+ FloatArray: TypeAlias = npt.NDArray[np.float_]
93
+ FloatMatrix: TypeAlias = npt.NDArray[np.float_]
94
+ else: # pragma: no cover - runtime fallback without NumPy
95
+ FloatArray: TypeAlias = Any
96
+ FloatMatrix: TypeAlias = Any
97
+
98
+ Graph: TypeAlias = TNFRGraph
99
+ #: Backwards-compatible alias for :data:`TNFRGraph`.
100
+
101
+ NodeId: TypeAlias = Hashable
102
+ #: Hashable identifier for a coherent TNFR node.
103
+
104
+ Node: TypeAlias = NodeId
105
+ #: Backwards-compatible alias for :data:`NodeId`.
106
+
107
+ NodeInitAttrMap: TypeAlias = MutableMapping[str, float]
108
+ #: Mutable mapping storing scalar node attributes during initialization.
109
+
110
+ GammaSpec: TypeAlias = Mapping[str, Any]
111
+ #: Mapping describing Γ evaluation parameters for a node or graph.
112
+
113
+ EPIValue: TypeAlias = float
114
+ #: Scalar Primary Information Structure value carried by a node.
115
+
116
+ DeltaNFR: TypeAlias = float
117
+ #: Scalar internal reorganisation driver ΔNFR applied to a node.
118
+
119
+ SecondDerivativeEPI: TypeAlias = float
120
+ #: Second derivative ∂²EPI/∂t² tracking bifurcation pressure.
121
+
122
+ Phase: TypeAlias = float
123
+ #: Phase (φ) describing a node's synchrony relative to its neighbors.
124
+
125
+ StructuralFrequency: TypeAlias = float
126
+ #: Structural frequency νf expressed in Hz_str.
127
+
128
+ SenseIndex: TypeAlias = float
129
+ #: Sense index Si capturing a node's reorganising capacity.
130
+
131
+ CouplingWeight: TypeAlias = float
132
+ #: Weight attached to edges describing coupling coherence strength.
133
+
134
+ CoherenceMetric: TypeAlias = float
135
+ #: Aggregated measure of coherence such as C(t) or Si.
136
+
137
+ TimingContext: TypeAlias = ContextManager[None]
138
+ #: Context manager used to measure execution time for cache operations.
139
+
140
+ ProgramTokens: TypeAlias = Sequence[_Token]
141
+ #: Sequence of execution tokens composing a TNFR program.
142
+
143
+ PresetTokens: TypeAlias = Sequence[_Token]
144
+ #: Sequence of execution tokens composing a preset program.
145
+
146
+ ArgSpec: TypeAlias = tuple[str, Mapping[str, Any]]
147
+ #: CLI argument specification pairing an option flag with keyword arguments.
148
+
149
+
150
+ TNFRConfigScalar: TypeAlias = bool | int | float | str | None
151
+ """Primitive value allowed within TNFR configuration stores."""
152
+
153
+ TNFRConfigSequence: TypeAlias = Sequence[TNFRConfigScalar]
154
+ """Homogeneous sequence of scalar TNFR configuration values."""
155
+
156
+ TNFRConfigValue: TypeAlias = (
157
+ TNFRConfigScalar | TNFRConfigSequence | Mapping[str, "TNFRConfigValue"]
158
+ )
159
+ """Permissible configuration entry for TNFR coherence defaults.
160
+
161
+ The alias captures the recursive structure used by TNFR defaults: scalars
162
+ express structural thresholds, booleans toggle operators, and nested mappings
163
+ or sequences describe coherent parameter bundles such as γ grammars,
164
+ selector advice or trace capture lists.
165
+ """
166
+
167
+
168
+ class _SigmaVectorRequired(TypedDict):
169
+ """Mandatory components for a σ-vector in the sense plane."""
170
+
171
+ x: float
172
+ y: float
173
+ mag: float
174
+ angle: float
175
+ n: int
176
+
177
+
178
+ class _SigmaVectorOptional(TypedDict, total=False):
179
+ """Optional metadata captured when tracking σ-vectors."""
180
+
181
+ glyph: str
182
+ w: float
183
+ t: float
184
+
185
+
186
+ class SigmaVector(_SigmaVectorRequired, _SigmaVectorOptional):
187
+ """Typed dictionary describing σ-vector telemetry."""
188
+
189
+
190
+ class SelectorThresholds(TypedDict):
191
+ """Normalised thresholds applied by the glyph selector."""
192
+
193
+ si_hi: float
194
+ si_lo: float
195
+ dnfr_hi: float
196
+ dnfr_lo: float
197
+ accel_hi: float
198
+ accel_lo: float
199
+
200
+
201
+ class SelectorWeights(TypedDict):
202
+ """Normalised weights controlling selector scoring."""
203
+
204
+ w_si: float
205
+ w_dnfr: float
206
+ w_accel: float
207
+
208
+
209
+ SelectorMetrics: TypeAlias = tuple[float, float, float]
210
+ """Tuple grouping normalised Si, |ΔNFR| and acceleration values."""
211
+
212
+ SelectorNorms: TypeAlias = Mapping[str, float]
213
+ """Mapping storing maxima used to normalise selector metrics."""
214
+
215
+
216
+ class _DeltaNFRHookProtocol(Protocol):
217
+ """Callable signature expected for ΔNFR update hooks.
218
+
219
+ Hooks receive the graph instance and may expose optional keyword
220
+ arguments such as ``n_jobs`` or cache controls. Additional positional
221
+ arguments are reserved for future extensions and ignored by the core
222
+ engine, keeping compatibility with user-provided hooks that only need the
223
+ graph reference.
224
+ """
225
+
226
+ def __call__(
227
+ self,
228
+ graph: TNFRGraph,
229
+ /,
230
+ *args: Any,
231
+ **kwargs: Any,
232
+ ) -> None:
233
+ ...
234
+
235
+
236
+ DeltaNFRHook: TypeAlias = _DeltaNFRHookProtocol
237
+ #: Callable hook invoked to compute ΔNFR for a :data:`TNFRGraph`.
238
+
239
+
240
+ class GraphLike(Protocol):
241
+ """Protocol for graph objects used throughout TNFR metrics.
242
+
243
+ The metrics helpers assume a single coherent graph interface so that
244
+ coherence, resonance and derived indicators read/write data through the
245
+ same structural access points.
246
+ """
247
+
248
+ graph: dict[str, Any]
249
+
250
+ def nodes(self, data: bool = ...) -> Iterable[Any]:
251
+ ...
252
+
253
+ def number_of_nodes(self) -> int:
254
+ ...
255
+
256
+ def neighbors(self, n: Any) -> Iterable[Any]:
257
+ ...
258
+
259
+ def __iter__(self) -> Iterable[Any]:
260
+ ...
261
+
262
+
263
+ class IntegratorProtocol(Protocol):
264
+ """Interface describing configurable nodal equation integrators."""
265
+
266
+ def integrate(
267
+ self,
268
+ graph: TNFRGraph,
269
+ *,
270
+ dt: float | None,
271
+ t: float | None,
272
+ method: str | None,
273
+ n_jobs: int | None,
274
+ ) -> None:
275
+ ...
276
+
277
+
278
+ class Glyph(str, Enum):
279
+ """Canonical TNFR glyphs."""
280
+
281
+ AL = "AL"
282
+ EN = "EN"
283
+ IL = "IL"
284
+ OZ = "OZ"
285
+ UM = "UM"
286
+ RA = "RA"
287
+ SHA = "SHA"
288
+ VAL = "VAL"
289
+ NUL = "NUL"
290
+ THOL = "THOL"
291
+ ZHIR = "ZHIR"
292
+ NAV = "NAV"
293
+ REMESH = "REMESH"
294
+
295
+
296
+ GlyphLoadDistribution: TypeAlias = dict[Glyph | str, float]
297
+ #: Normalised glyph load proportions keyed by :class:`Glyph` or aggregate labels.
298
+
299
+ class _SelectorLifecycle(Protocol):
300
+ """Protocol describing the selector lifecycle supported by the runtime."""
301
+
302
+ def __call__(self, graph: TNFRGraph, node: NodeId) -> Glyph | str:
303
+ ...
304
+
305
+ def prepare(self, graph: TNFRGraph, nodes: Sequence[NodeId]) -> None:
306
+ ...
307
+
308
+ def select(self, graph: TNFRGraph, node: NodeId) -> Glyph | str:
309
+ ...
310
+
311
+
312
+ GlyphSelector: TypeAlias = (
313
+ Callable[[TNFRGraph, NodeId], Glyph | str] | _SelectorLifecycle
314
+ )
315
+ #: Selector callable or object returning the glyph to apply for ``NodeId``.
316
+
317
+ SelectorPreselectionMetrics: TypeAlias = Mapping[Any, SelectorMetrics]
318
+ #: Mapping of nodes to their normalised selector metrics.
319
+
320
+ SelectorPreselectionChoices: TypeAlias = Mapping[Any, Glyph | str]
321
+ #: Mapping of nodes to their preferred glyph choices prior to grammar filters.
322
+
323
+ SelectorPreselectionPayload: TypeAlias = tuple[
324
+ SelectorPreselectionMetrics,
325
+ SelectorPreselectionChoices,
326
+ ]
327
+ #: Tuple grouping selector metrics and base decisions for preselection steps.
328
+
329
+ TraceFieldFn: TypeAlias = Callable[[TNFRGraph], "TraceMetadata"]
330
+ #: Callable producing :class:`tnfr.trace.TraceMetadata` from a :data:`TNFRGraph`.
331
+
332
+ TraceFieldMap: TypeAlias = Mapping[str, "TraceFieldFn"]
333
+ #: Mapping of trace field names to their producers for a given phase.
334
+
335
+ TraceFieldRegistry: TypeAlias = dict[str, dict[str, "TraceFieldFn"]]
336
+ #: Registry grouping trace field producers by capture phase.
337
+
338
+ HistoryState: TypeAlias = _HistoryDict | dict[str, Any]
339
+ #: History container used to accumulate glyph metrics and logs for the graph.
340
+
341
+ TraceCallback: TypeAlias = Callable[[TNFRGraph, dict[str, Any]], None]
342
+ #: Callback signature used by :func:`tnfr.trace.register_trace`.
343
+
344
+ DiagnosisNodeData: TypeAlias = Mapping[str, Any]
345
+ #: Raw nodal measurement payload used prior to computing diagnostics.
346
+
347
+ DiagnosisSharedState: TypeAlias = Mapping[str, Any]
348
+ #: Shared read-only state propagated to diagnosis workers.
349
+
350
+ DiagnosisPayload: TypeAlias = dict[str, Any]
351
+ #: Structured diagnostics exported for a single node.
352
+
353
+ DiagnosisResult: TypeAlias = tuple[NodeId, DiagnosisPayload]
354
+ #: Node identifier paired with its :data:`DiagnosisPayload`.
355
+
356
+ DiagnosisPayloadChunk: TypeAlias = list[DiagnosisNodeData]
357
+ #: Chunk of nodal payloads processed together by diagnosis workers.
358
+
359
+ DiagnosisResultList: TypeAlias = list[DiagnosisResult]
360
+ #: Collection of diagnosis results matching worker output shape.
361
+
362
+ DnfrCacheVectors: TypeAlias = tuple[
363
+ np.ndarray | None,
364
+ np.ndarray | None,
365
+ np.ndarray | None,
366
+ np.ndarray | None,
367
+ np.ndarray | None,
368
+ ]
369
+ """Tuple grouping cached NumPy vectors for θ, EPI, νf and trigonometric projections."""
370
+
371
+ DnfrVectorMap: TypeAlias = dict[str, np.ndarray | None]
372
+ """Mapping of TNFR state aliases to their NumPy buffers synchronized from lists."""
373
+
374
+ NeighborStats: TypeAlias = tuple[
375
+ Sequence[float],
376
+ Sequence[float],
377
+ Sequence[float],
378
+ Sequence[float],
379
+ Sequence[float] | None,
380
+ Sequence[float] | None,
381
+ Sequence[float] | None,
382
+ ]
383
+ """Bundle of neighbour accumulators for cosine, sine, EPI, νf and topology totals."""
tnfr/types.pyi ADDED
@@ -0,0 +1,145 @@
1
+ from typing import Any, Callable, ContextManager, Iterable, Protocol, cast
2
+ from collections.abc import Hashable, Mapping, Sequence
3
+ from enum import Enum
4
+ from typing import TypedDict
5
+
6
+ from ._compat import TypeAlias
7
+
8
+ try:
9
+ import networkx as nx # type: ignore[import-not-found]
10
+ except Exception:
11
+ class _FallbackGraph: ...
12
+
13
+ class _FallbackNetworkX:
14
+ Graph = _FallbackGraph
15
+
16
+ nx = cast(Any, _FallbackNetworkX())
17
+
18
+ try:
19
+ import numpy as np # type: ignore[import-not-found]
20
+ except Exception:
21
+ class _FallbackNdArray: ...
22
+
23
+ class _FallbackNumpy:
24
+ ndarray = _FallbackNdArray
25
+
26
+ np = cast(Any, _FallbackNumpy())
27
+
28
+ from .tokens import Token
29
+ from .trace import TraceMetadata
30
+ from .glyph_history import HistoryDict as _HistoryDict
31
+
32
+ __all__: tuple[str, ...]
33
+
34
+ def __getattr__(name: str) -> Any: ...
35
+
36
+ TNFRGraph: TypeAlias = nx.Graph
37
+ Graph: TypeAlias = TNFRGraph
38
+ NodeId: TypeAlias = Hashable
39
+ Node: TypeAlias = NodeId
40
+ GammaSpec: TypeAlias = Mapping[str, Any]
41
+ EPIValue: TypeAlias = float
42
+ DeltaNFR: TypeAlias = float
43
+ SecondDerivativeEPI: TypeAlias = float
44
+ Phase: TypeAlias = float
45
+ StructuralFrequency: TypeAlias = float
46
+ SenseIndex: TypeAlias = float
47
+ CouplingWeight: TypeAlias = float
48
+ CoherenceMetric: TypeAlias = float
49
+ TimingContext: TypeAlias = ContextManager[None]
50
+ PresetTokens: TypeAlias = Sequence[Token]
51
+
52
+
53
+ class SelectorThresholds(TypedDict):
54
+ si_hi: float
55
+ si_lo: float
56
+ dnfr_hi: float
57
+ dnfr_lo: float
58
+ accel_hi: float
59
+ accel_lo: float
60
+
61
+
62
+ class SelectorWeights(TypedDict):
63
+ w_si: float
64
+ w_dnfr: float
65
+ w_accel: float
66
+
67
+
68
+ SelectorMetrics: TypeAlias = tuple[float, float, float]
69
+ SelectorNorms: TypeAlias = Mapping[str, float]
70
+
71
+ class _DeltaNFRHookProtocol(Protocol):
72
+ def __call__(self, graph: TNFRGraph, /, *args: Any, **kwargs: Any) -> None: ...
73
+
74
+ DeltaNFRHook: TypeAlias = _DeltaNFRHookProtocol
75
+
76
+ class GraphLike(Protocol):
77
+ graph: dict[str, Any]
78
+
79
+ def nodes(self, data: bool = ...) -> Iterable[Any]: ...
80
+ def number_of_nodes(self) -> int: ...
81
+ def neighbors(self, n: Any) -> Iterable[Any]: ...
82
+ def __iter__(self) -> Iterable[Any]: ...
83
+
84
+ class IntegratorProtocol(Protocol):
85
+ def integrate(
86
+ self,
87
+ graph: TNFRGraph,
88
+ *,
89
+ dt: float | None = ...,
90
+ t: float | None = ...,
91
+ method: str | None = ...,
92
+ n_jobs: int | None = ...,
93
+ ) -> None: ...
94
+
95
+ class Glyph(str, Enum):
96
+ AL = "AL"
97
+ EN = "EN"
98
+ IL = "IL"
99
+ OZ = "OZ"
100
+ UM = "UM"
101
+ RA = "RA"
102
+ SHA = "SHA"
103
+ VAL = "VAL"
104
+ NUL = "NUL"
105
+ THOL = "THOL"
106
+ ZHIR = "ZHIR"
107
+ NAV = "NAV"
108
+ REMESH = "REMESH"
109
+
110
+ GlyphLoadDistribution: TypeAlias = dict[Glyph | str, float]
111
+ GlyphSelector: TypeAlias = Callable[[TNFRGraph, NodeId], Glyph | str]
112
+ SelectorPreselectionMetrics: TypeAlias = Mapping[Any, SelectorMetrics]
113
+ SelectorPreselectionChoices: TypeAlias = Mapping[Any, Glyph | str]
114
+ SelectorPreselectionPayload: TypeAlias = tuple[
115
+ SelectorPreselectionMetrics,
116
+ SelectorPreselectionChoices,
117
+ ]
118
+ TraceFieldFn: TypeAlias = Callable[[TNFRGraph], TraceMetadata]
119
+ TraceFieldMap: TypeAlias = Mapping[str, TraceFieldFn]
120
+ TraceFieldRegistry: TypeAlias = dict[str, dict[str, TraceFieldFn]]
121
+ HistoryState: TypeAlias = _HistoryDict | dict[str, Any]
122
+ TraceCallback: TypeAlias = Callable[[TNFRGraph, dict[str, Any]], None]
123
+ DiagnosisNodeData: TypeAlias = Mapping[str, Any]
124
+ DiagnosisSharedState: TypeAlias = Mapping[str, Any]
125
+ DiagnosisPayload: TypeAlias = dict[str, Any]
126
+ DiagnosisResult: TypeAlias = tuple[NodeId, DiagnosisPayload]
127
+ DiagnosisPayloadChunk: TypeAlias = list[DiagnosisNodeData]
128
+ DiagnosisResultList: TypeAlias = list[DiagnosisResult]
129
+ DnfrCacheVectors: TypeAlias = tuple[
130
+ np.ndarray | None,
131
+ np.ndarray | None,
132
+ np.ndarray | None,
133
+ np.ndarray | None,
134
+ np.ndarray | None,
135
+ ]
136
+ DnfrVectorMap: TypeAlias = dict[str, np.ndarray | None]
137
+ NeighborStats: TypeAlias = tuple[
138
+ Sequence[float],
139
+ Sequence[float],
140
+ Sequence[float],
141
+ Sequence[float],
142
+ Sequence[float] | None,
143
+ Sequence[float] | None,
144
+ Sequence[float] | None,
145
+ ]