tnfr 6.0.0__py3-none-any.whl → 7.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.

Potentially problematic release.


This version of tnfr might be problematic. Click here for more details.

Files changed (176) hide show
  1. tnfr/__init__.py +50 -5
  2. tnfr/__init__.pyi +0 -7
  3. tnfr/_compat.py +0 -1
  4. tnfr/_generated_version.py +34 -0
  5. tnfr/_version.py +44 -2
  6. tnfr/alias.py +14 -13
  7. tnfr/alias.pyi +5 -37
  8. tnfr/cache.py +9 -729
  9. tnfr/cache.pyi +8 -224
  10. tnfr/callback_utils.py +16 -31
  11. tnfr/callback_utils.pyi +3 -29
  12. tnfr/cli/__init__.py +17 -11
  13. tnfr/cli/__init__.pyi +0 -21
  14. tnfr/cli/arguments.py +175 -14
  15. tnfr/cli/arguments.pyi +5 -11
  16. tnfr/cli/execution.py +434 -48
  17. tnfr/cli/execution.pyi +14 -24
  18. tnfr/cli/utils.py +20 -3
  19. tnfr/cli/utils.pyi +5 -5
  20. tnfr/config/__init__.py +2 -1
  21. tnfr/config/__init__.pyi +2 -0
  22. tnfr/config/feature_flags.py +83 -0
  23. tnfr/config/init.py +1 -1
  24. tnfr/config/operator_names.py +1 -14
  25. tnfr/config/presets.py +6 -26
  26. tnfr/constants/__init__.py +10 -13
  27. tnfr/constants/__init__.pyi +10 -22
  28. tnfr/constants/aliases.py +31 -0
  29. tnfr/constants/core.py +4 -3
  30. tnfr/constants/init.py +1 -1
  31. tnfr/constants/metric.py +3 -3
  32. tnfr/dynamics/__init__.py +64 -10
  33. tnfr/dynamics/__init__.pyi +3 -4
  34. tnfr/dynamics/adaptation.py +79 -13
  35. tnfr/dynamics/aliases.py +10 -9
  36. tnfr/dynamics/coordination.py +77 -35
  37. tnfr/dynamics/dnfr.py +575 -274
  38. tnfr/dynamics/dnfr.pyi +1 -10
  39. tnfr/dynamics/integrators.py +47 -33
  40. tnfr/dynamics/integrators.pyi +0 -1
  41. tnfr/dynamics/runtime.py +489 -129
  42. tnfr/dynamics/sampling.py +2 -0
  43. tnfr/dynamics/selectors.py +101 -62
  44. tnfr/execution.py +15 -8
  45. tnfr/execution.pyi +5 -25
  46. tnfr/flatten.py +7 -3
  47. tnfr/flatten.pyi +1 -8
  48. tnfr/gamma.py +22 -26
  49. tnfr/gamma.pyi +0 -6
  50. tnfr/glyph_history.py +37 -26
  51. tnfr/glyph_history.pyi +1 -19
  52. tnfr/glyph_runtime.py +16 -0
  53. tnfr/glyph_runtime.pyi +9 -0
  54. tnfr/immutable.py +20 -15
  55. tnfr/immutable.pyi +4 -7
  56. tnfr/initialization.py +5 -7
  57. tnfr/initialization.pyi +1 -9
  58. tnfr/io.py +6 -305
  59. tnfr/io.pyi +13 -8
  60. tnfr/mathematics/__init__.py +81 -0
  61. tnfr/mathematics/backend.py +426 -0
  62. tnfr/mathematics/dynamics.py +398 -0
  63. tnfr/mathematics/epi.py +254 -0
  64. tnfr/mathematics/generators.py +222 -0
  65. tnfr/mathematics/metrics.py +119 -0
  66. tnfr/mathematics/operators.py +233 -0
  67. tnfr/mathematics/operators_factory.py +71 -0
  68. tnfr/mathematics/projection.py +78 -0
  69. tnfr/mathematics/runtime.py +173 -0
  70. tnfr/mathematics/spaces.py +247 -0
  71. tnfr/mathematics/transforms.py +292 -0
  72. tnfr/metrics/__init__.py +10 -10
  73. tnfr/metrics/coherence.py +123 -94
  74. tnfr/metrics/common.py +22 -13
  75. tnfr/metrics/common.pyi +42 -11
  76. tnfr/metrics/core.py +72 -14
  77. tnfr/metrics/diagnosis.py +48 -57
  78. tnfr/metrics/diagnosis.pyi +3 -7
  79. tnfr/metrics/export.py +3 -5
  80. tnfr/metrics/glyph_timing.py +41 -31
  81. tnfr/metrics/reporting.py +13 -6
  82. tnfr/metrics/sense_index.py +884 -114
  83. tnfr/metrics/trig.py +167 -11
  84. tnfr/metrics/trig.pyi +1 -0
  85. tnfr/metrics/trig_cache.py +112 -15
  86. tnfr/node.py +400 -17
  87. tnfr/node.pyi +55 -38
  88. tnfr/observers.py +111 -8
  89. tnfr/observers.pyi +0 -15
  90. tnfr/ontosim.py +9 -6
  91. tnfr/ontosim.pyi +0 -5
  92. tnfr/operators/__init__.py +529 -42
  93. tnfr/operators/__init__.pyi +14 -0
  94. tnfr/operators/definitions.py +350 -18
  95. tnfr/operators/definitions.pyi +0 -14
  96. tnfr/operators/grammar.py +760 -0
  97. tnfr/operators/jitter.py +28 -22
  98. tnfr/operators/registry.py +7 -12
  99. tnfr/operators/registry.pyi +0 -2
  100. tnfr/operators/remesh.py +38 -61
  101. tnfr/rng.py +17 -300
  102. tnfr/schemas/__init__.py +8 -0
  103. tnfr/schemas/grammar.json +94 -0
  104. tnfr/selector.py +3 -4
  105. tnfr/selector.pyi +1 -1
  106. tnfr/sense.py +22 -24
  107. tnfr/sense.pyi +0 -7
  108. tnfr/structural.py +504 -21
  109. tnfr/structural.pyi +41 -18
  110. tnfr/telemetry/__init__.py +23 -1
  111. tnfr/telemetry/cache_metrics.py +226 -0
  112. tnfr/telemetry/nu_f.py +423 -0
  113. tnfr/telemetry/nu_f.pyi +123 -0
  114. tnfr/tokens.py +1 -4
  115. tnfr/tokens.pyi +1 -6
  116. tnfr/trace.py +20 -53
  117. tnfr/trace.pyi +9 -37
  118. tnfr/types.py +244 -15
  119. tnfr/types.pyi +200 -14
  120. tnfr/units.py +69 -0
  121. tnfr/units.pyi +16 -0
  122. tnfr/utils/__init__.py +107 -48
  123. tnfr/utils/__init__.pyi +80 -11
  124. tnfr/utils/cache.py +1705 -65
  125. tnfr/utils/cache.pyi +370 -58
  126. tnfr/utils/chunks.py +104 -0
  127. tnfr/utils/chunks.pyi +21 -0
  128. tnfr/utils/data.py +95 -5
  129. tnfr/utils/data.pyi +8 -17
  130. tnfr/utils/graph.py +2 -4
  131. tnfr/utils/init.py +31 -7
  132. tnfr/utils/init.pyi +4 -11
  133. tnfr/utils/io.py +313 -14
  134. tnfr/{helpers → utils}/numeric.py +50 -24
  135. tnfr/utils/numeric.pyi +21 -0
  136. tnfr/validation/__init__.py +92 -4
  137. tnfr/validation/__init__.pyi +77 -17
  138. tnfr/validation/compatibility.py +79 -43
  139. tnfr/validation/compatibility.pyi +4 -6
  140. tnfr/validation/grammar.py +55 -133
  141. tnfr/validation/grammar.pyi +37 -8
  142. tnfr/validation/graph.py +138 -0
  143. tnfr/validation/graph.pyi +17 -0
  144. tnfr/validation/rules.py +161 -74
  145. tnfr/validation/rules.pyi +55 -18
  146. tnfr/validation/runtime.py +263 -0
  147. tnfr/validation/runtime.pyi +31 -0
  148. tnfr/validation/soft_filters.py +170 -0
  149. tnfr/validation/soft_filters.pyi +37 -0
  150. tnfr/validation/spectral.py +159 -0
  151. tnfr/validation/spectral.pyi +46 -0
  152. tnfr/validation/syntax.py +28 -139
  153. tnfr/validation/syntax.pyi +7 -4
  154. tnfr/validation/window.py +39 -0
  155. tnfr/validation/window.pyi +1 -0
  156. tnfr/viz/__init__.py +9 -0
  157. tnfr/viz/matplotlib.py +246 -0
  158. {tnfr-6.0.0.dist-info → tnfr-7.0.0.dist-info}/METADATA +63 -19
  159. tnfr-7.0.0.dist-info/RECORD +185 -0
  160. {tnfr-6.0.0.dist-info → tnfr-7.0.0.dist-info}/licenses/LICENSE.md +1 -1
  161. tnfr/constants_glyphs.py +0 -16
  162. tnfr/constants_glyphs.pyi +0 -12
  163. tnfr/grammar.py +0 -25
  164. tnfr/grammar.pyi +0 -13
  165. tnfr/helpers/__init__.py +0 -151
  166. tnfr/helpers/__init__.pyi +0 -66
  167. tnfr/helpers/numeric.pyi +0 -12
  168. tnfr/presets.py +0 -15
  169. tnfr/presets.pyi +0 -7
  170. tnfr/utils/io.pyi +0 -10
  171. tnfr/utils/validators.py +0 -130
  172. tnfr/utils/validators.pyi +0 -19
  173. tnfr-6.0.0.dist-info/RECORD +0 -157
  174. {tnfr-6.0.0.dist-info → tnfr-7.0.0.dist-info}/WHEEL +0 -0
  175. {tnfr-6.0.0.dist-info → tnfr-7.0.0.dist-info}/entry_points.txt +0 -0
  176. {tnfr-6.0.0.dist-info → tnfr-7.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,292 @@
1
+ """Canonical transform contracts for TNFR coherence tooling.
2
+
3
+ This module intentionally provides *contracts* rather than concrete
4
+ implementations. Phase 2 of the mathematics roadmap will plug the actual
5
+ algorithms into these helpers. Until then, the functions below raise
6
+ ``NotImplementedError`` with descriptive guidance so downstream modules know
7
+ which structural guarantees each helper must provide.
8
+
9
+ The three exposed contracts cover:
10
+
11
+ ``build_isometry_factory``
12
+ Expected to output callables that embed or project states while preserving
13
+ the TNFR structural metric. Implementations must return operators whose
14
+ adjoint composes to identity inside the target Hilbert or Banach space so
15
+ no coherence is lost during modal changes.
16
+
17
+ ``validate_norm_preservation``
18
+ Should perform diagnostic checks that a provided transform keeps the
19
+ νf-aligned norm invariant (within tolerance) across representative states.
20
+ Validation must surface informative errors so simulation pipelines can
21
+ gate potentially destructive transforms before they act on an EPI.
22
+
23
+ ``ensure_coherence_monotonicity``
24
+ Designed to assert that a transform (or sequence thereof) does not break
25
+ the monotonic coherence requirements captured in the repo-wide invariants.
26
+ Implementations should report any drop in ``C(t)`` outside authorised
27
+ dissonance windows and annotate the offending timestep to ease triage.
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ import logging
33
+ from dataclasses import dataclass
34
+ from typing import Callable, Iterable, Mapping, Protocol, Sequence, Union, runtime_checkable
35
+
36
+ import numpy as np
37
+
38
+ from .epi import BEPIElement
39
+
40
+ logger = logging.getLogger(__name__)
41
+
42
+ __all__ = [
43
+ "CoherenceMonotonicityReport",
44
+ "CoherenceViolation",
45
+ "IsometryFactory",
46
+ "build_isometry_factory",
47
+ "validate_norm_preservation",
48
+ "ensure_coherence_monotonicity",
49
+ ]
50
+
51
+
52
+ @runtime_checkable
53
+ class IsometryFactory(Protocol):
54
+ """Callable creating isometric transforms aligned with TNFR semantics.
55
+
56
+ Implementations produced by :func:`build_isometry_factory` must accept a
57
+ structural basis (modal decomposition, eigenvectors, or similar spectral
58
+ anchors) and return a transform that preserves both the vector norm and the
59
+ encoded coherence structure. The returned callable should accept the raw
60
+ state data and emit the mapped state in the target representation while
61
+ guaranteeing ``T* · T == I`` on the relevant space.
62
+ """
63
+
64
+ def __call__(
65
+ self,
66
+ *,
67
+ basis: Sequence[Sequence[complex]] | None = None,
68
+ enforce_phase: bool = True,
69
+ ) -> Callable[[Sequence[complex]], Sequence[complex]]:
70
+ """Return an isometric transform for the provided basis."""
71
+
72
+
73
+ def build_isometry_factory(
74
+ *,
75
+ source_dimension: int,
76
+ target_dimension: int,
77
+ allow_expansion: bool = False,
78
+ ) -> IsometryFactory:
79
+ """Create a factory for constructing TNFR-aligned isometries.
80
+
81
+ Parameters
82
+ ----------
83
+ source_dimension:
84
+ Dimensionality of the input structural space.
85
+ target_dimension:
86
+ Dimensionality of the destination structural space. When the target
87
+ dimension is larger than the source, implementations must specify how
88
+ coherence is embedded without dilution.
89
+ allow_expansion:
90
+ Flag indicating whether the isometry may expand into a higher
91
+ dimensional space (still norm-preserving via padding and phase guards).
92
+
93
+ Returns
94
+ -------
95
+ IsometryFactory
96
+ A callable that can produce concrete isometries on demand once a basis
97
+ or spectral frame is available.
98
+ """
99
+
100
+ raise NotImplementedError(
101
+ "Phase 2 will provide the canonical TNFR isometry factory; "
102
+ "current stage only documents the expected contract."
103
+ )
104
+
105
+
106
+ def validate_norm_preservation(
107
+ transform: Callable[[Sequence[complex]], Sequence[complex]],
108
+ *,
109
+ probes: Iterable[Sequence[complex]],
110
+ metric: Callable[[Sequence[complex]], float],
111
+ atol: float = 1e-9,
112
+ ) -> None:
113
+ """Assert that a transform preserves the TNFR structural norm.
114
+
115
+ The validator should iterate through ``probes`` (representative EPI states)
116
+ and confirm that applying ``transform`` leaves the provided ``metric``
117
+ unchanged within ``atol``. Any detected drift must be reported via
118
+ exceptions that include the offending probe and the measured deviation so
119
+ callers can attribute potential coherence loss to specific conditions.
120
+ """
121
+
122
+ raise NotImplementedError(
123
+ "Norm preservation checks will be introduced in Phase 2; implementers "
124
+ "should ensure transform(metric(state)) == metric(state) within atol."
125
+ )
126
+
127
+
128
+ @dataclass(frozen=True)
129
+ class CoherenceViolation:
130
+ """Details about a monotonicity violation detected in a coherence trace."""
131
+
132
+ index: int
133
+ previous_value: float
134
+ current_value: float
135
+ tolerated_drop: float
136
+ drop: float
137
+ kind: str
138
+
139
+
140
+ @dataclass(frozen=True)
141
+ class CoherenceMonotonicityReport:
142
+ """Structured report generated by :func:`ensure_coherence_monotonicity`."""
143
+
144
+ coherence_values: tuple[float, ...]
145
+ violations: tuple[CoherenceViolation, ...]
146
+ allow_plateaus: bool
147
+ tolerated_drop: float
148
+ atol: float
149
+
150
+ @property
151
+ def is_monotonic(self) -> bool:
152
+ """Return ``True`` when no violations were recorded."""
153
+
154
+ return not self.violations
155
+
156
+
157
+ def _as_coherence_values(
158
+ coherence_series: Sequence[Union[float, BEPIElement]],
159
+ *,
160
+ space: "BanachSpaceEPI" | None,
161
+ norm_kwargs: Mapping[str, float],
162
+ ) -> tuple[float, ...]:
163
+ if not coherence_series:
164
+ raise ValueError("coherence_series must contain at least one entry.")
165
+
166
+ first = coherence_series[0]
167
+ if isinstance(first, BEPIElement):
168
+ from .spaces import BanachSpaceEPI # Local import to avoid circular dependency
169
+
170
+ working_space = space if space is not None else BanachSpaceEPI()
171
+ values = []
172
+ for element in coherence_series:
173
+ if not isinstance(element, BEPIElement):
174
+ raise TypeError(
175
+ "All entries must be BEPIElement instances when the series contains BEPI data.",
176
+ )
177
+ value = working_space.coherence_norm(
178
+ element.f_continuous,
179
+ element.a_discrete,
180
+ x_grid=element.x_grid,
181
+ **norm_kwargs,
182
+ )
183
+ values.append(float(value))
184
+ return tuple(values)
185
+
186
+ values = []
187
+ for value in coherence_series:
188
+ if isinstance(value, BEPIElement):
189
+ raise TypeError(
190
+ "All entries must be numeric when the series is treated as coherence values.",
191
+ )
192
+ numeric = float(value)
193
+ if not np.isfinite(numeric):
194
+ raise ValueError("Coherence values must be finite numbers.")
195
+ values.append(numeric)
196
+ return tuple(values)
197
+
198
+
199
+ def ensure_coherence_monotonicity(
200
+ coherence_series: Sequence[Union[float, BEPIElement]],
201
+ *,
202
+ allow_plateaus: bool = True,
203
+ tolerated_drop: float = 0.0,
204
+ atol: float = 1e-9,
205
+ space: "BanachSpaceEPI" | None = None,
206
+ norm_kwargs: Mapping[str, float] | None = None,
207
+ ) -> CoherenceMonotonicityReport:
208
+ """Validate monotonic behaviour of coherence measurements ``C(t)``.
209
+
210
+ Parameters
211
+ ----------
212
+ coherence_series:
213
+ Ordered sequence of coherence measurements (as floats) or
214
+ :class:`BEPIElement` instances recorded after each transform
215
+ application.
216
+ allow_plateaus:
217
+ When ``True`` the contract tolerates flat segments, otherwise every
218
+ subsequent value must strictly increase.
219
+ tolerated_drop:
220
+ Maximum allowed temporary decrease in coherence, representing approved
221
+ dissonance windows. Values greater than zero should only appear when a
222
+ higher-level scenario explicitly references controlled dissonance tests.
223
+
224
+ Returns
225
+ -------
226
+ CoherenceMonotonicityReport
227
+ Structured report describing the evaluated coherence trajectory and any
228
+ detected violations. Callers can inspect ``report.is_monotonic`` to
229
+ determine whether the constraint holds.
230
+ """
231
+
232
+ if tolerated_drop < 0:
233
+ raise ValueError("tolerated_drop must be non-negative.")
234
+ if atol < 0:
235
+ raise ValueError("atol must be non-negative.")
236
+
237
+ if norm_kwargs is None:
238
+ norm_kwargs = {}
239
+
240
+ values = _as_coherence_values(coherence_series, space=space, norm_kwargs=norm_kwargs)
241
+
242
+ violations: list[CoherenceViolation] = []
243
+
244
+ for index in range(1, len(values)):
245
+ previous_value = values[index - 1]
246
+ current_value = values[index]
247
+ drop = previous_value - current_value
248
+
249
+ if current_value + tolerated_drop + atol < previous_value:
250
+ violation = CoherenceViolation(
251
+ index=index,
252
+ previous_value=previous_value,
253
+ current_value=current_value,
254
+ tolerated_drop=tolerated_drop,
255
+ drop=drop,
256
+ kind="drop",
257
+ )
258
+ violations.append(violation)
259
+ logger.warning(
260
+ "Coherence drop detected at step %s: previous=%s current=%s tolerated_drop=%s",
261
+ index,
262
+ previous_value,
263
+ current_value,
264
+ tolerated_drop,
265
+ )
266
+ continue
267
+
268
+ if not allow_plateaus and current_value <= previous_value + atol:
269
+ violation = CoherenceViolation(
270
+ index=index,
271
+ previous_value=previous_value,
272
+ current_value=current_value,
273
+ tolerated_drop=tolerated_drop,
274
+ drop=max(0.0, drop),
275
+ kind="plateau",
276
+ )
277
+ violations.append(violation)
278
+ logger.warning(
279
+ "Coherence plateau detected at step %s: previous=%s current=%s",
280
+ index,
281
+ previous_value,
282
+ current_value,
283
+ )
284
+
285
+ return CoherenceMonotonicityReport(
286
+ coherence_values=values,
287
+ violations=tuple(violations),
288
+ allow_plateaus=allow_plateaus,
289
+ tolerated_drop=tolerated_drop,
290
+ atol=atol,
291
+ )
292
+
tnfr/metrics/__init__.py CHANGED
@@ -2,26 +2,26 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from .core import register_metrics_callbacks
6
- from .reporting import (
7
- Tg_global,
8
- Tg_by_node,
9
- latency_series,
10
- glyphogram_series,
11
- glyph_top,
12
- build_metrics_summary,
13
- )
14
5
  from .coherence import (
15
6
  coherence_matrix,
16
7
  local_phase_sync,
17
8
  local_phase_sync_weighted,
18
9
  register_coherence_callbacks,
19
10
  )
11
+ from .core import register_metrics_callbacks
20
12
  from .diagnosis import (
21
- register_diagnosis_callbacks,
22
13
  dissonance_events,
14
+ register_diagnosis_callbacks,
23
15
  )
24
16
  from .export import export_metrics
17
+ from .reporting import (
18
+ Tg_by_node,
19
+ Tg_global,
20
+ build_metrics_summary,
21
+ glyph_top,
22
+ glyphogram_series,
23
+ latency_series,
24
+ )
25
25
 
26
26
  __all__ = (
27
27
  "register_metrics_callbacks",