tnfr 4.5.2__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 (195) hide show
  1. tnfr/__init__.py +275 -51
  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 +117 -31
  8. tnfr/alias.pyi +108 -0
  9. tnfr/cache.py +6 -572
  10. tnfr/cache.pyi +16 -0
  11. tnfr/callback_utils.py +16 -38
  12. tnfr/callback_utils.pyi +79 -0
  13. tnfr/cli/__init__.py +34 -14
  14. tnfr/cli/__init__.pyi +26 -0
  15. tnfr/cli/arguments.py +211 -28
  16. tnfr/cli/arguments.pyi +27 -0
  17. tnfr/cli/execution.py +470 -50
  18. tnfr/cli/execution.pyi +70 -0
  19. tnfr/cli/utils.py +18 -3
  20. tnfr/cli/utils.pyi +8 -0
  21. tnfr/config/__init__.py +13 -0
  22. tnfr/config/__init__.pyi +10 -0
  23. tnfr/{constants_glyphs.py → config/constants.py} +26 -20
  24. tnfr/config/constants.pyi +12 -0
  25. tnfr/config/feature_flags.py +83 -0
  26. tnfr/{config.py → config/init.py} +11 -7
  27. tnfr/config/init.pyi +8 -0
  28. tnfr/config/operator_names.py +93 -0
  29. tnfr/config/operator_names.pyi +28 -0
  30. tnfr/config/presets.py +84 -0
  31. tnfr/config/presets.pyi +7 -0
  32. tnfr/constants/__init__.py +80 -29
  33. tnfr/constants/__init__.pyi +92 -0
  34. tnfr/constants/aliases.py +31 -0
  35. tnfr/constants/core.py +4 -4
  36. tnfr/constants/core.pyi +17 -0
  37. tnfr/constants/init.py +1 -1
  38. tnfr/constants/init.pyi +12 -0
  39. tnfr/constants/metric.py +7 -15
  40. tnfr/constants/metric.pyi +19 -0
  41. tnfr/dynamics/__init__.py +165 -633
  42. tnfr/dynamics/__init__.pyi +82 -0
  43. tnfr/dynamics/adaptation.py +267 -0
  44. tnfr/dynamics/aliases.py +23 -0
  45. tnfr/dynamics/coordination.py +385 -0
  46. tnfr/dynamics/dnfr.py +2283 -400
  47. tnfr/dynamics/dnfr.pyi +24 -0
  48. tnfr/dynamics/integrators.py +406 -98
  49. tnfr/dynamics/integrators.pyi +34 -0
  50. tnfr/dynamics/runtime.py +881 -0
  51. tnfr/dynamics/sampling.py +10 -5
  52. tnfr/dynamics/sampling.pyi +7 -0
  53. tnfr/dynamics/selectors.py +719 -0
  54. tnfr/execution.py +70 -48
  55. tnfr/execution.pyi +45 -0
  56. tnfr/flatten.py +13 -9
  57. tnfr/flatten.pyi +21 -0
  58. tnfr/gamma.py +66 -53
  59. tnfr/gamma.pyi +34 -0
  60. tnfr/glyph_history.py +110 -52
  61. tnfr/glyph_history.pyi +35 -0
  62. tnfr/glyph_runtime.py +16 -0
  63. tnfr/glyph_runtime.pyi +9 -0
  64. tnfr/immutable.py +69 -28
  65. tnfr/immutable.pyi +34 -0
  66. tnfr/initialization.py +16 -16
  67. tnfr/initialization.pyi +65 -0
  68. tnfr/io.py +6 -240
  69. tnfr/io.pyi +16 -0
  70. tnfr/locking.pyi +7 -0
  71. tnfr/mathematics/__init__.py +81 -0
  72. tnfr/mathematics/backend.py +426 -0
  73. tnfr/mathematics/dynamics.py +398 -0
  74. tnfr/mathematics/epi.py +254 -0
  75. tnfr/mathematics/generators.py +222 -0
  76. tnfr/mathematics/metrics.py +119 -0
  77. tnfr/mathematics/operators.py +233 -0
  78. tnfr/mathematics/operators_factory.py +71 -0
  79. tnfr/mathematics/projection.py +78 -0
  80. tnfr/mathematics/runtime.py +173 -0
  81. tnfr/mathematics/spaces.py +247 -0
  82. tnfr/mathematics/transforms.py +292 -0
  83. tnfr/metrics/__init__.py +10 -10
  84. tnfr/metrics/__init__.pyi +20 -0
  85. tnfr/metrics/coherence.py +993 -324
  86. tnfr/metrics/common.py +23 -16
  87. tnfr/metrics/common.pyi +46 -0
  88. tnfr/metrics/core.py +251 -35
  89. tnfr/metrics/core.pyi +13 -0
  90. tnfr/metrics/diagnosis.py +708 -111
  91. tnfr/metrics/diagnosis.pyi +85 -0
  92. tnfr/metrics/export.py +27 -15
  93. tnfr/metrics/glyph_timing.py +232 -42
  94. tnfr/metrics/reporting.py +33 -22
  95. tnfr/metrics/reporting.pyi +12 -0
  96. tnfr/metrics/sense_index.py +987 -43
  97. tnfr/metrics/sense_index.pyi +9 -0
  98. tnfr/metrics/trig.py +214 -23
  99. tnfr/metrics/trig.pyi +13 -0
  100. tnfr/metrics/trig_cache.py +115 -22
  101. tnfr/metrics/trig_cache.pyi +10 -0
  102. tnfr/node.py +542 -136
  103. tnfr/node.pyi +178 -0
  104. tnfr/observers.py +152 -35
  105. tnfr/observers.pyi +31 -0
  106. tnfr/ontosim.py +23 -19
  107. tnfr/ontosim.pyi +28 -0
  108. tnfr/operators/__init__.py +601 -82
  109. tnfr/operators/__init__.pyi +45 -0
  110. tnfr/operators/definitions.py +513 -0
  111. tnfr/operators/definitions.pyi +78 -0
  112. tnfr/operators/grammar.py +760 -0
  113. tnfr/operators/jitter.py +107 -38
  114. tnfr/operators/jitter.pyi +11 -0
  115. tnfr/operators/registry.py +75 -0
  116. tnfr/operators/registry.pyi +13 -0
  117. tnfr/operators/remesh.py +149 -88
  118. tnfr/py.typed +0 -0
  119. tnfr/rng.py +46 -143
  120. tnfr/rng.pyi +14 -0
  121. tnfr/schemas/__init__.py +8 -0
  122. tnfr/schemas/grammar.json +94 -0
  123. tnfr/selector.py +25 -19
  124. tnfr/selector.pyi +19 -0
  125. tnfr/sense.py +72 -62
  126. tnfr/sense.pyi +23 -0
  127. tnfr/structural.py +522 -262
  128. tnfr/structural.pyi +69 -0
  129. tnfr/telemetry/__init__.py +35 -0
  130. tnfr/telemetry/cache_metrics.py +226 -0
  131. tnfr/telemetry/nu_f.py +423 -0
  132. tnfr/telemetry/nu_f.pyi +123 -0
  133. tnfr/telemetry/verbosity.py +37 -0
  134. tnfr/tokens.py +1 -3
  135. tnfr/tokens.pyi +36 -0
  136. tnfr/trace.py +270 -113
  137. tnfr/trace.pyi +40 -0
  138. tnfr/types.py +574 -6
  139. tnfr/types.pyi +331 -0
  140. tnfr/units.py +69 -0
  141. tnfr/units.pyi +16 -0
  142. tnfr/utils/__init__.py +217 -0
  143. tnfr/utils/__init__.pyi +202 -0
  144. tnfr/utils/cache.py +2395 -0
  145. tnfr/utils/cache.pyi +468 -0
  146. tnfr/utils/chunks.py +104 -0
  147. tnfr/utils/chunks.pyi +21 -0
  148. tnfr/{collections_utils.py → utils/data.py} +147 -90
  149. tnfr/utils/data.pyi +64 -0
  150. tnfr/utils/graph.py +85 -0
  151. tnfr/utils/graph.pyi +10 -0
  152. tnfr/utils/init.py +770 -0
  153. tnfr/utils/init.pyi +78 -0
  154. tnfr/utils/io.py +456 -0
  155. tnfr/{helpers → utils}/numeric.py +51 -24
  156. tnfr/utils/numeric.pyi +21 -0
  157. tnfr/validation/__init__.py +113 -0
  158. tnfr/validation/__init__.pyi +77 -0
  159. tnfr/validation/compatibility.py +95 -0
  160. tnfr/validation/compatibility.pyi +6 -0
  161. tnfr/validation/grammar.py +71 -0
  162. tnfr/validation/grammar.pyi +40 -0
  163. tnfr/validation/graph.py +138 -0
  164. tnfr/validation/graph.pyi +17 -0
  165. tnfr/validation/rules.py +281 -0
  166. tnfr/validation/rules.pyi +55 -0
  167. tnfr/validation/runtime.py +263 -0
  168. tnfr/validation/runtime.pyi +31 -0
  169. tnfr/validation/soft_filters.py +170 -0
  170. tnfr/validation/soft_filters.pyi +37 -0
  171. tnfr/validation/spectral.py +159 -0
  172. tnfr/validation/spectral.pyi +46 -0
  173. tnfr/validation/syntax.py +40 -0
  174. tnfr/validation/syntax.pyi +10 -0
  175. tnfr/validation/window.py +39 -0
  176. tnfr/validation/window.pyi +1 -0
  177. tnfr/viz/__init__.py +9 -0
  178. tnfr/viz/matplotlib.py +246 -0
  179. tnfr-7.0.0.dist-info/METADATA +179 -0
  180. tnfr-7.0.0.dist-info/RECORD +185 -0
  181. {tnfr-4.5.2.dist-info → tnfr-7.0.0.dist-info}/licenses/LICENSE.md +1 -1
  182. tnfr/grammar.py +0 -344
  183. tnfr/graph_utils.py +0 -84
  184. tnfr/helpers/__init__.py +0 -71
  185. tnfr/import_utils.py +0 -228
  186. tnfr/json_utils.py +0 -162
  187. tnfr/logging_utils.py +0 -116
  188. tnfr/presets.py +0 -60
  189. tnfr/validators.py +0 -84
  190. tnfr/value_utils.py +0 -59
  191. tnfr-4.5.2.dist-info/METADATA +0 -379
  192. tnfr-4.5.2.dist-info/RECORD +0 -67
  193. {tnfr-4.5.2.dist-info → tnfr-7.0.0.dist-info}/WHEEL +0 -0
  194. {tnfr-4.5.2.dist-info → tnfr-7.0.0.dist-info}/entry_points.txt +0 -0
  195. {tnfr-4.5.2.dist-info → tnfr-7.0.0.dist-info}/top_level.txt +0 -0
tnfr/structural.pyi ADDED
@@ -0,0 +1,69 @@
1
+ from typing import TYPE_CHECKING, Any, Callable, Hashable, Iterable, Sequence
2
+
3
+ from .validation import SequenceValidationResult
4
+ from .operators.definitions import (
5
+ Coherence,
6
+ Contraction,
7
+ Coupling,
8
+ Dissonance,
9
+ Emission,
10
+ Expansion,
11
+ Mutation,
12
+ Operator,
13
+ Reception,
14
+ Recursivity,
15
+ Resonance,
16
+ SelfOrganization,
17
+ Silence,
18
+ Transition,
19
+ )
20
+
21
+ if TYPE_CHECKING:
22
+ import networkx as nx
23
+ from .mathematics import (
24
+ BasicStateProjector,
25
+ CoherenceOperator,
26
+ FrequencyOperator,
27
+ HilbertSpace,
28
+ MathematicalDynamicsEngine,
29
+ NFRValidator,
30
+ )
31
+
32
+ __all__: tuple[str, ...]
33
+
34
+ def __getattr__(name: str) -> Any: ...
35
+ def create_nfr(
36
+ name: str,
37
+ *,
38
+ epi: float = ...,
39
+ vf: float = ...,
40
+ theta: float = ...,
41
+ graph: "nx.Graph" | None = ...,
42
+ dnfr_hook: Callable[..., None] = ...,
43
+ ) -> tuple["nx.Graph", str]: ...
44
+ def create_math_nfr(
45
+ name: str,
46
+ *,
47
+ epi: float = ...,
48
+ vf: float = ...,
49
+ theta: float = ...,
50
+ graph: "nx.Graph" | None = ...,
51
+ dnfr_hook: Callable[..., None] = ...,
52
+ dimension: int | None = ...,
53
+ hilbert_space: "HilbertSpace" | None = ...,
54
+ coherence_operator: "CoherenceOperator" | None = ...,
55
+ coherence_spectrum: Sequence[float] | None = ...,
56
+ coherence_c_min: float | None = ...,
57
+ coherence_threshold: float | None = ...,
58
+ frequency_operator: "FrequencyOperator" | None = ...,
59
+ frequency_diagonal: Sequence[float] | None = ...,
60
+ generator_diagonal: Sequence[float] | None = ...,
61
+ state_projector: "BasicStateProjector" | None = ...,
62
+ dynamics_engine: "MathematicalDynamicsEngine" | None = ...,
63
+ validator: "NFRValidator" | None = ...,
64
+ ) -> tuple["nx.Graph", str]: ...
65
+
66
+ OPERATORS: dict[str, Operator]
67
+
68
+ def validate_sequence(names: Iterable[str]) -> SequenceValidationResult: ...
69
+ def run_sequence(G: "nx.Graph", node: Hashable, ops: Iterable[Operator]) -> None: ...
@@ -0,0 +1,35 @@
1
+ """Telemetry helpers for shared observability settings."""
2
+
3
+ from .cache_metrics import (
4
+ CacheMetricsSnapshot,
5
+ CacheTelemetryPublisher,
6
+ ensure_cache_metrics_publisher,
7
+ publish_graph_cache_metrics,
8
+ )
9
+ from .nu_f import (
10
+ NuFSnapshot,
11
+ NuFTelemetryAccumulator,
12
+ NuFWindow,
13
+ ensure_nu_f_telemetry,
14
+ record_nu_f_window,
15
+ )
16
+ from .verbosity import (
17
+ TELEMETRY_VERBOSITY_DEFAULT,
18
+ TELEMETRY_VERBOSITY_LEVELS,
19
+ TelemetryVerbosity,
20
+ )
21
+
22
+ __all__ = [
23
+ "CacheMetricsSnapshot",
24
+ "CacheTelemetryPublisher",
25
+ "ensure_cache_metrics_publisher",
26
+ "publish_graph_cache_metrics",
27
+ "NuFWindow",
28
+ "NuFSnapshot",
29
+ "NuFTelemetryAccumulator",
30
+ "ensure_nu_f_telemetry",
31
+ "record_nu_f_window",
32
+ "TelemetryVerbosity",
33
+ "TELEMETRY_VERBOSITY_DEFAULT",
34
+ "TELEMETRY_VERBOSITY_LEVELS",
35
+ ]
@@ -0,0 +1,226 @@
1
+ """Cache telemetry publishers for structured observability channels."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import weakref
7
+ from dataclasses import dataclass
8
+ from typing import Any, MutableMapping, TYPE_CHECKING
9
+
10
+ from ..utils import (
11
+ _graph_cache_manager,
12
+ CacheManager,
13
+ CacheStatistics,
14
+ get_logger,
15
+ json_dumps,
16
+ )
17
+
18
+ if TYPE_CHECKING: # pragma: no cover - typing helpers
19
+ from networkx import Graph
20
+
21
+ from ..types import TNFRGraph
22
+
23
+ __all__ = (
24
+ "CacheMetricsSnapshot",
25
+ "CacheTelemetryPublisher",
26
+ "ensure_cache_metrics_publisher",
27
+ "publish_graph_cache_metrics",
28
+ )
29
+
30
+
31
+ @dataclass(frozen=True)
32
+ class CacheMetricsSnapshot:
33
+ """Structured cache metrics enriched with ratios and latency estimates."""
34
+
35
+ cache: str
36
+ hits: int
37
+ misses: int
38
+ evictions: int
39
+ total_time: float
40
+ timings: int
41
+ hit_ratio: float | None
42
+ miss_ratio: float | None
43
+ avg_latency: float | None
44
+
45
+ @classmethod
46
+ def from_statistics(
47
+ cls, name: str, stats: CacheStatistics
48
+ ) -> "CacheMetricsSnapshot":
49
+ """Build a snapshot computing ratios from :class:`CacheStatistics`."""
50
+
51
+ hits = int(stats.hits)
52
+ misses = int(stats.misses)
53
+ evictions = int(stats.evictions)
54
+ total_time = float(stats.total_time)
55
+ timings = int(stats.timings)
56
+ requests = hits + misses
57
+ hit_ratio = (hits / requests) if requests else None
58
+ miss_ratio = (misses / requests) if requests else None
59
+ avg_latency = (total_time / timings) if timings else None
60
+ return cls(
61
+ cache=name,
62
+ hits=hits,
63
+ misses=misses,
64
+ evictions=evictions,
65
+ total_time=total_time,
66
+ timings=timings,
67
+ hit_ratio=hit_ratio,
68
+ miss_ratio=miss_ratio,
69
+ avg_latency=avg_latency,
70
+ )
71
+
72
+ def as_payload(self) -> dict[str, Any]:
73
+ """Return a dictionary suitable for structured logging."""
74
+
75
+ return {
76
+ "cache": self.cache,
77
+ "hits": self.hits,
78
+ "misses": self.misses,
79
+ "evictions": self.evictions,
80
+ "total_time": self.total_time,
81
+ "timings": self.timings,
82
+ "hit_ratio": self.hit_ratio,
83
+ "miss_ratio": self.miss_ratio,
84
+ "avg_latency": self.avg_latency,
85
+ }
86
+
87
+
88
+ class CacheTelemetryPublisher:
89
+ """Metrics publisher broadcasting cache counters to observability channels."""
90
+
91
+ def __init__(
92
+ self,
93
+ *,
94
+ graph: "TNFRGraph | Graph | MutableMapping[str, Any] | None" = None,
95
+ logger: logging.Logger | None = None,
96
+ hit_ratio_alert: float = 0.5,
97
+ latency_alert: float = 0.1,
98
+ ) -> None:
99
+ self._logger = logger or get_logger("tnfr.telemetry.cache")
100
+ self._graph_ref: weakref.ReferenceType[
101
+ "TNFRGraph | Graph | MutableMapping[str, Any]"
102
+ ] | None = None
103
+ self._hit_ratio_alert = float(hit_ratio_alert)
104
+ self._latency_alert = float(latency_alert)
105
+ self.attach_graph(graph)
106
+
107
+ @property
108
+ def logger(self) -> logging.Logger:
109
+ """Logger used for structured cache telemetry."""
110
+
111
+ return self._logger
112
+
113
+ def attach_graph(
114
+ self, graph: "TNFRGraph | Graph | MutableMapping[str, Any] | None"
115
+ ) -> None:
116
+ """Attach ``graph`` so observability callbacks receive metrics."""
117
+
118
+ if graph is None:
119
+ return
120
+ try:
121
+ self._graph_ref = weakref.ref(graph) # type: ignore[arg-type]
122
+ except TypeError: # pragma: no cover - defensive path for exotic graphs
123
+ self._graph_ref = None
124
+
125
+ def _resolve_graph(
126
+ self,
127
+ ) -> "TNFRGraph | Graph | MutableMapping[str, Any] | None":
128
+ return self._graph_ref() if self._graph_ref is not None else None
129
+
130
+ def __call__(self, name: str, stats: CacheStatistics) -> None:
131
+ """Emit structured telemetry and invoke observability hooks."""
132
+
133
+ snapshot = CacheMetricsSnapshot.from_statistics(name, stats)
134
+ payload = snapshot.as_payload()
135
+ message = json_dumps({"event": "cache_metrics", **payload}, sort_keys=True)
136
+ self._logger.info(message)
137
+
138
+ if (
139
+ snapshot.hit_ratio is not None
140
+ and snapshot.hit_ratio < self._hit_ratio_alert
141
+ and snapshot.misses > 0
142
+ ):
143
+ warning = json_dumps(
144
+ {
145
+ "event": "cache_metrics.low_hit_ratio",
146
+ "cache": name,
147
+ "hit_ratio": snapshot.hit_ratio,
148
+ "threshold": self._hit_ratio_alert,
149
+ "requests": snapshot.hits + snapshot.misses,
150
+ },
151
+ sort_keys=True,
152
+ )
153
+ self._logger.warning(warning)
154
+
155
+ if (
156
+ snapshot.avg_latency is not None
157
+ and snapshot.avg_latency > self._latency_alert
158
+ and snapshot.timings > 0
159
+ ):
160
+ warning = json_dumps(
161
+ {
162
+ "event": "cache_metrics.high_latency",
163
+ "cache": name,
164
+ "avg_latency": snapshot.avg_latency,
165
+ "threshold": self._latency_alert,
166
+ "timings": snapshot.timings,
167
+ },
168
+ sort_keys=True,
169
+ )
170
+ self._logger.warning(warning)
171
+
172
+ graph = self._resolve_graph()
173
+ if graph is not None:
174
+ from ..callback_utils import CallbackEvent, callback_manager
175
+
176
+ ctx = {"cache": name, "metrics": payload}
177
+ callback_manager.invoke_callbacks(graph, CallbackEvent.CACHE_METRICS, ctx)
178
+
179
+
180
+ _PUBLISHER_ATTR = "_tnfr_cache_metrics_publisher"
181
+
182
+
183
+ def ensure_cache_metrics_publisher(
184
+ manager: CacheManager,
185
+ *,
186
+ graph: "TNFRGraph | Graph | MutableMapping[str, Any] | None" = None,
187
+ logger: logging.Logger | None = None,
188
+ hit_ratio_alert: float = 0.5,
189
+ latency_alert: float = 0.1,
190
+ ) -> CacheTelemetryPublisher:
191
+ """Attach a :class:`CacheTelemetryPublisher` to ``manager`` if missing."""
192
+
193
+ publisher = getattr(manager, _PUBLISHER_ATTR, None)
194
+ if not isinstance(publisher, CacheTelemetryPublisher):
195
+ publisher = CacheTelemetryPublisher(
196
+ graph=graph,
197
+ logger=logger,
198
+ hit_ratio_alert=hit_ratio_alert,
199
+ latency_alert=latency_alert,
200
+ )
201
+ manager.register_metrics_publisher(publisher)
202
+ setattr(manager, _PUBLISHER_ATTR, publisher)
203
+ else:
204
+ if graph is not None:
205
+ publisher.attach_graph(graph)
206
+ return publisher
207
+
208
+
209
+ def publish_graph_cache_metrics(
210
+ graph: "TNFRGraph | Graph | MutableMapping[str, Any]",
211
+ *,
212
+ manager: CacheManager | None = None,
213
+ hit_ratio_alert: float = 0.5,
214
+ latency_alert: float = 0.1,
215
+ ) -> None:
216
+ """Publish cache metrics for ``graph`` using the shared manager."""
217
+
218
+ if manager is None:
219
+ manager = _graph_cache_manager(getattr(graph, "graph", graph))
220
+ ensure_cache_metrics_publisher(
221
+ manager,
222
+ graph=graph,
223
+ hit_ratio_alert=hit_ratio_alert,
224
+ latency_alert=latency_alert,
225
+ )
226
+ manager.publish_metrics()