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
@@ -0,0 +1,45 @@
1
+ from typing import Any
2
+
3
+ Operator: Any
4
+ Emission: Any
5
+ Reception: Any
6
+ Coherence: Any
7
+ Dissonance: Any
8
+ Coupling: Any
9
+ Resonance: Any
10
+ Silence: Any
11
+ Expansion: Any
12
+ Contraction: Any
13
+ SelfOrganization: Any
14
+ Mutation: Any
15
+ Transition: Any
16
+ Recursivity: Any
17
+ GLYPH_OPERATIONS: Any
18
+ JitterCache: Any
19
+ JitterCacheManager: Any
20
+ OPERATORS: Any
21
+ GrammarContext: Any
22
+ StructuralGrammarError: Any
23
+ RepeatWindowError: Any
24
+ MutationPreconditionError: Any
25
+ TholClosureError: Any
26
+ TransitionCompatibilityError: Any
27
+ SequenceValidationResult: Any
28
+ SequenceSyntaxError: Any
29
+ _gram_state: Any
30
+ apply_glyph: Any
31
+ apply_glyph_obj: Any
32
+ apply_glyph_with_grammar: Any
33
+ apply_network_remesh: Any
34
+ apply_remesh_if_globally_stable: Any
35
+ apply_topological_remesh: Any
36
+ discover_operators: Any
37
+ enforce_canonical_grammar: Any
38
+ get_glyph_factors: Any
39
+ get_jitter_manager: Any
40
+ get_neighbor_epi: Any
41
+ on_applied_glyph: Any
42
+ parse_sequence: Any
43
+ random_jitter: Any
44
+ reset_jitter_manager: Any
45
+ validate_sequence: Any
@@ -0,0 +1,513 @@
1
+ """Definitions for canonical TNFR structural operators.
2
+
3
+ English identifiers are the public API. Spanish wrappers were removed in
4
+ TNFR 2.0, so downstream code must import these classes directly.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Any, ClassVar
10
+
11
+ from ..config.operator_names import (
12
+ COHERENCE,
13
+ CONTRACTION,
14
+ COUPLING,
15
+ DISSONANCE,
16
+ EMISSION,
17
+ EXPANSION,
18
+ MUTATION,
19
+ RECEPTION,
20
+ RECURSIVITY,
21
+ RESONANCE,
22
+ SELF_ORGANIZATION,
23
+ SILENCE,
24
+ TRANSITION,
25
+ )
26
+ from ..types import Glyph, TNFRGraph
27
+ from .registry import register_operator
28
+
29
+ __all__ = [
30
+ "Operator",
31
+ "Emission",
32
+ "Reception",
33
+ "Coherence",
34
+ "Dissonance",
35
+ "Coupling",
36
+ "Resonance",
37
+ "Silence",
38
+ "Expansion",
39
+ "Contraction",
40
+ "SelfOrganization",
41
+ "Mutation",
42
+ "Transition",
43
+ "Recursivity",
44
+ ]
45
+
46
+
47
+ class Operator:
48
+ """Base class for TNFR operators.
49
+
50
+ Each operator defines ``name`` (ASCII identifier) and ``glyph``. Calling an
51
+ instance applies the corresponding glyph to the node.
52
+ """
53
+
54
+ name: ClassVar[str] = "operator"
55
+ glyph: ClassVar[Glyph | None] = None
56
+
57
+ def __call__(self, G: TNFRGraph, node: Any, **kw: Any) -> None:
58
+ """Apply the operator glyph to ``node`` under canonical grammar control.
59
+
60
+ Parameters
61
+ ----------
62
+ G : TNFRGraph
63
+ Graph storing TNFR nodes, their coherence telemetry and glyph
64
+ history.
65
+ node : Any
66
+ Identifier or object representing the target node within ``G``.
67
+ **kw : Any
68
+ Additional keyword arguments forwarded to the grammar layer.
69
+ Supported keys include ``window`` to constrain the grammar window
70
+ affected by the glyph application.
71
+
72
+ Raises
73
+ ------
74
+ NotImplementedError
75
+ If ``glyph`` is :data:`None`, meaning the operator has not been
76
+ bound to a structural glyph.
77
+
78
+ Notes
79
+ -----
80
+ The invocation delegates to
81
+ :func:`tnfr.operators.grammar.apply_glyph_with_grammar`, which enforces
82
+ the TNFR grammar before activating the glyph. The grammar may expand,
83
+ contract or stabilise the neighbourhood so that the operator preserves
84
+ canonical closure and coherence.
85
+ """
86
+ if self.glyph is None:
87
+ raise NotImplementedError("Operator without assigned glyph")
88
+ from . import apply_glyph_with_grammar
89
+
90
+ apply_glyph_with_grammar(G, [node], self.glyph, kw.get("window"))
91
+
92
+
93
+ @register_operator
94
+ class Emission(Operator):
95
+ """Seed coherence by projecting the emission structural pattern.
96
+
97
+ Activates glyph ``AL`` to initialise outward resonance around a nascent
98
+ node.
99
+
100
+ Examples
101
+ --------
102
+ >>> from tnfr.constants import DNFR_PRIMARY, EPI_PRIMARY, VF_PRIMARY
103
+ >>> from tnfr.dynamics import set_delta_nfr_hook
104
+ >>> from tnfr.structural import create_nfr, run_sequence
105
+ >>> from tnfr.operators.definitions import Emission
106
+ >>> G, node = create_nfr("seed", epi=0.18, vf=1.0)
107
+ >>> increments = iter([(0.07, 0.02)])
108
+ >>> def scripted_delta(graph):
109
+ ... d_epi, d_vf = next(increments)
110
+ ... graph.nodes[node][DNFR_PRIMARY] = d_epi
111
+ ... graph.nodes[node][EPI_PRIMARY] += d_epi
112
+ ... graph.nodes[node][VF_PRIMARY] += d_vf
113
+ >>> set_delta_nfr_hook(G, scripted_delta)
114
+ >>> run_sequence(G, node, [Emission()])
115
+ >>> round(G.nodes[node][EPI_PRIMARY], 2)
116
+ 0.25
117
+ >>> round(G.nodes[node][VF_PRIMARY], 2)
118
+ 1.02
119
+ """
120
+
121
+ __slots__ = ()
122
+ name: ClassVar[str] = EMISSION
123
+ glyph: ClassVar[Glyph] = Glyph.AL
124
+
125
+
126
+ @register_operator
127
+ class Reception(Operator):
128
+ """Stabilise inbound energy to strengthen a node's receptivity.
129
+
130
+ Activates glyph ``EN`` to anchor external coherence into the node's EPI.
131
+
132
+ Examples
133
+ --------
134
+ >>> from tnfr.constants import DNFR_PRIMARY, EPI_PRIMARY
135
+ >>> from tnfr.dynamics import set_delta_nfr_hook
136
+ >>> from tnfr.structural import create_nfr, run_sequence
137
+ >>> from tnfr.operators.definitions import Reception
138
+ >>> G, node = create_nfr("receiver", epi=0.30)
139
+ >>> G.nodes[node][DNFR_PRIMARY] = 0.12
140
+ >>> increments = iter([(0.05,)])
141
+ >>> def stabilise(graph):
142
+ ... (d_epi,) = next(increments)
143
+ ... graph.nodes[node][EPI_PRIMARY] += d_epi
144
+ ... graph.nodes[node][DNFR_PRIMARY] *= 0.5
145
+ >>> set_delta_nfr_hook(G, stabilise)
146
+ >>> run_sequence(G, node, [Reception()])
147
+ >>> round(G.nodes[node][EPI_PRIMARY], 2)
148
+ 0.35
149
+ >>> round(G.nodes[node][DNFR_PRIMARY], 2)
150
+ 0.06
151
+ """
152
+
153
+ __slots__ = ()
154
+ name: ClassVar[str] = RECEPTION
155
+ glyph: ClassVar[Glyph] = Glyph.EN
156
+
157
+
158
+ @register_operator
159
+ class Coherence(Operator):
160
+ """Reinforce structural alignment across the node and its neighbours.
161
+
162
+ Activates glyph ``IL`` to compress ΔNFR drift and raise the local C(t).
163
+
164
+ Examples
165
+ --------
166
+ >>> from tnfr.constants import DNFR_PRIMARY, EPI_PRIMARY, VF_PRIMARY
167
+ >>> from tnfr.dynamics import set_delta_nfr_hook
168
+ >>> from tnfr.structural import create_nfr, run_sequence
169
+ >>> from tnfr.operators.definitions import Coherence
170
+ >>> G, node = create_nfr("core", epi=0.50, vf=1.10)
171
+ >>> G.nodes[node][DNFR_PRIMARY] = 0.08
172
+ >>> adjustments = iter([(0.03, 0.04, -0.03)])
173
+ >>> def align(graph):
174
+ ... d_epi, d_vf, d_dnfr = next(adjustments)
175
+ ... graph.nodes[node][EPI_PRIMARY] += d_epi
176
+ ... graph.nodes[node][VF_PRIMARY] += d_vf
177
+ ... graph.nodes[node][DNFR_PRIMARY] += d_dnfr
178
+ >>> set_delta_nfr_hook(G, align)
179
+ >>> run_sequence(G, node, [Coherence()])
180
+ >>> round(G.nodes[node][EPI_PRIMARY], 2)
181
+ 0.53
182
+ >>> round(G.nodes[node][VF_PRIMARY], 2)
183
+ 1.14
184
+ >>> round(G.nodes[node][DNFR_PRIMARY], 2)
185
+ 0.05
186
+ """
187
+
188
+ __slots__ = ()
189
+ name: ClassVar[str] = COHERENCE
190
+ glyph: ClassVar[Glyph] = Glyph.IL
191
+
192
+
193
+ @register_operator
194
+ class Dissonance(Operator):
195
+ """Inject controlled dissonance to probe structural robustness.
196
+
197
+ Activates glyph ``OZ`` to widen ΔNFR and test bifurcation thresholds.
198
+
199
+ Examples
200
+ --------
201
+ >>> from tnfr.constants import DNFR_PRIMARY, THETA_PRIMARY
202
+ >>> from tnfr.dynamics import set_delta_nfr_hook
203
+ >>> from tnfr.structural import create_nfr, run_sequence
204
+ >>> from tnfr.operators.definitions import Dissonance
205
+ >>> G, node = create_nfr("probe", theta=0.10)
206
+ >>> G.nodes[node][DNFR_PRIMARY] = 0.02
207
+ >>> shocks = iter([(0.09, 0.15)])
208
+ >>> def inject(graph):
209
+ ... d_dnfr, d_theta = next(shocks)
210
+ ... graph.nodes[node][DNFR_PRIMARY] += d_dnfr
211
+ ... graph.nodes[node][THETA_PRIMARY] += d_theta
212
+ >>> set_delta_nfr_hook(G, inject)
213
+ >>> run_sequence(G, node, [Dissonance()])
214
+ >>> round(G.nodes[node][DNFR_PRIMARY], 2)
215
+ 0.11
216
+ >>> round(G.nodes[node][THETA_PRIMARY], 2)
217
+ 0.25
218
+ """
219
+
220
+ __slots__ = ()
221
+ name: ClassVar[str] = DISSONANCE
222
+ glyph: ClassVar[Glyph] = Glyph.OZ
223
+
224
+
225
+ @register_operator
226
+ class Coupling(Operator):
227
+ """Bind nodes by synchronising their coupling phase and bandwidth.
228
+
229
+ Activates glyph ``UM`` to stabilise bidirectional coherence links.
230
+
231
+ Examples
232
+ --------
233
+ >>> from tnfr.constants import DNFR_PRIMARY, THETA_PRIMARY, VF_PRIMARY
234
+ >>> from tnfr.dynamics import set_delta_nfr_hook
235
+ >>> from tnfr.structural import create_nfr, run_sequence
236
+ >>> from tnfr.operators.definitions import Coupling
237
+ >>> G, node = create_nfr("pair", vf=1.20, theta=0.50)
238
+ >>> alignments = iter([(-0.18, 0.03, 0.02)])
239
+ >>> def synchronise(graph):
240
+ ... d_theta, d_vf, residual_dnfr = next(alignments)
241
+ ... graph.nodes[node][THETA_PRIMARY] += d_theta
242
+ ... graph.nodes[node][VF_PRIMARY] += d_vf
243
+ ... graph.nodes[node][DNFR_PRIMARY] = residual_dnfr
244
+ >>> set_delta_nfr_hook(G, synchronise)
245
+ >>> run_sequence(G, node, [Coupling()])
246
+ >>> round(G.nodes[node][THETA_PRIMARY], 2)
247
+ 0.32
248
+ >>> round(G.nodes[node][VF_PRIMARY], 2)
249
+ 1.23
250
+ >>> round(G.nodes[node][DNFR_PRIMARY], 2)
251
+ 0.02
252
+ """
253
+
254
+ __slots__ = ()
255
+ name: ClassVar[str] = COUPLING
256
+ glyph: ClassVar[Glyph] = Glyph.UM
257
+
258
+
259
+ @register_operator
260
+ class Resonance(Operator):
261
+ """Amplify shared frequency so the node propagates coherent resonance.
262
+
263
+ Activates glyph ``RA`` to circulate phase-aligned energy through the
264
+ network.
265
+
266
+ Examples
267
+ --------
268
+ >>> from tnfr.constants import DNFR_PRIMARY, VF_PRIMARY
269
+ >>> from tnfr.dynamics import set_delta_nfr_hook
270
+ >>> from tnfr.structural import create_nfr, run_sequence
271
+ >>> from tnfr.operators.definitions import Resonance
272
+ >>> G, node = create_nfr("carrier", vf=0.90)
273
+ >>> pulses = iter([(0.05, 0.03)])
274
+ >>> def amplify(graph):
275
+ ... d_vf, d_dnfr = next(pulses)
276
+ ... graph.nodes[node][VF_PRIMARY] += d_vf
277
+ ... graph.nodes[node][DNFR_PRIMARY] = d_dnfr
278
+ >>> set_delta_nfr_hook(G, amplify)
279
+ >>> run_sequence(G, node, [Resonance()])
280
+ >>> round(G.nodes[node][VF_PRIMARY], 2)
281
+ 0.95
282
+ >>> round(G.nodes[node][DNFR_PRIMARY], 2)
283
+ 0.03
284
+ """
285
+
286
+ __slots__ = ()
287
+ name: ClassVar[str] = RESONANCE
288
+ glyph: ClassVar[Glyph] = Glyph.RA
289
+
290
+
291
+ @register_operator
292
+ class Silence(Operator):
293
+ """Suspend reorganisation to preserve the node's current coherence state.
294
+
295
+ Activates glyph ``SHA`` to lower νf and hold the local EPI invariant.
296
+
297
+ Examples
298
+ --------
299
+ >>> from tnfr.constants import DNFR_PRIMARY, EPI_PRIMARY, VF_PRIMARY
300
+ >>> from tnfr.dynamics import set_delta_nfr_hook
301
+ >>> from tnfr.structural import create_nfr, run_sequence
302
+ >>> from tnfr.operators.definitions import Silence
303
+ >>> G, node = create_nfr("rest", epi=0.51, vf=1.00)
304
+ >>> def freeze(graph):
305
+ ... graph.nodes[node][DNFR_PRIMARY] = 0.0
306
+ ... graph.nodes[node][VF_PRIMARY] = 0.02
307
+ ... # EPI is intentionally left untouched to preserve the stored form.
308
+ >>> set_delta_nfr_hook(G, freeze)
309
+ >>> run_sequence(G, node, [Silence()])
310
+ >>> round(G.nodes[node][EPI_PRIMARY], 2)
311
+ 0.51
312
+ >>> round(G.nodes[node][VF_PRIMARY], 2)
313
+ 0.02
314
+ """
315
+
316
+ __slots__ = ()
317
+ name: ClassVar[str] = SILENCE
318
+ glyph: ClassVar[Glyph] = Glyph.SHA
319
+
320
+
321
+ @register_operator
322
+ class Expansion(Operator):
323
+ """Dilate the node's structure to explore additional coherence volume.
324
+
325
+ Activates glyph ``VAL`` to unfold neighbouring trajectories and extend the
326
+ node's operational boundary.
327
+
328
+ Examples
329
+ --------
330
+ >>> from tnfr.constants import EPI_PRIMARY, VF_PRIMARY
331
+ >>> from tnfr.dynamics import set_delta_nfr_hook
332
+ >>> from tnfr.structural import create_nfr, run_sequence
333
+ >>> from tnfr.operators.definitions import Expansion
334
+ >>> G, node = create_nfr("theta", epi=0.47, vf=0.95)
335
+ >>> spreads = iter([(0.06, 0.08)])
336
+ >>> def open_volume(graph):
337
+ ... d_epi, d_vf = next(spreads)
338
+ ... graph.nodes[node][EPI_PRIMARY] += d_epi
339
+ ... graph.nodes[node][VF_PRIMARY] += d_vf
340
+ >>> set_delta_nfr_hook(G, open_volume)
341
+ >>> run_sequence(G, node, [Expansion()])
342
+ >>> round(G.nodes[node][EPI_PRIMARY], 2)
343
+ 0.53
344
+ >>> round(G.nodes[node][VF_PRIMARY], 2)
345
+ 1.03
346
+ """
347
+
348
+ __slots__ = ()
349
+ name: ClassVar[str] = EXPANSION
350
+ glyph: ClassVar[Glyph] = Glyph.VAL
351
+
352
+
353
+ @register_operator
354
+ class Contraction(Operator):
355
+ """Concentrate the node's structure to tighten coherence gradients.
356
+
357
+ Activates glyph ``NUL`` to pull peripheral trajectories back into the
358
+ core EPI.
359
+
360
+ Examples
361
+ --------
362
+ >>> from tnfr.constants import DNFR_PRIMARY, EPI_PRIMARY, VF_PRIMARY
363
+ >>> from tnfr.dynamics import set_delta_nfr_hook
364
+ >>> from tnfr.structural import create_nfr, run_sequence
365
+ >>> from tnfr.operators.definitions import Contraction
366
+ >>> G, node = create_nfr("iota", epi=0.39, vf=1.05)
367
+ >>> squeezes = iter([(-0.05, -0.03, 0.05)])
368
+ >>> def tighten(graph):
369
+ ... d_epi, d_vf, stored_dnfr = next(squeezes)
370
+ ... graph.nodes[node][EPI_PRIMARY] += d_epi
371
+ ... graph.nodes[node][VF_PRIMARY] += d_vf
372
+ ... graph.nodes[node][DNFR_PRIMARY] = stored_dnfr
373
+ >>> set_delta_nfr_hook(G, tighten)
374
+ >>> run_sequence(G, node, [Contraction()])
375
+ >>> round(G.nodes[node][EPI_PRIMARY], 2)
376
+ 0.34
377
+ >>> round(G.nodes[node][VF_PRIMARY], 2)
378
+ 1.02
379
+ >>> round(G.nodes[node][DNFR_PRIMARY], 2)
380
+ 0.05
381
+ """
382
+
383
+ __slots__ = ()
384
+ name: ClassVar[str] = CONTRACTION
385
+ glyph: ClassVar[Glyph] = Glyph.NUL
386
+
387
+
388
+ @register_operator
389
+ class SelfOrganization(Operator):
390
+ """Spawn nested EPIs so the node reorganises autonomously.
391
+
392
+ Activates glyph ``THOL`` to trigger self-organising cascades within the
393
+ local structure.
394
+
395
+ Examples
396
+ --------
397
+ >>> from tnfr.constants import EPI_PRIMARY, VF_PRIMARY
398
+ >>> from tnfr.dynamics import set_delta_nfr_hook
399
+ >>> from tnfr.structural import create_nfr, run_sequence
400
+ >>> from tnfr.operators.definitions import SelfOrganization
401
+ >>> G, node = create_nfr("kappa", epi=0.66, vf=1.10)
402
+ >>> cascades = iter([(0.04, 0.05)])
403
+ >>> def spawn(graph):
404
+ ... d_epi, d_vf = next(cascades)
405
+ ... graph.nodes[node][EPI_PRIMARY] += d_epi
406
+ ... graph.nodes[node][VF_PRIMARY] += d_vf
407
+ ... graph.graph.setdefault("sub_epi", []).append(round(graph.nodes[node][EPI_PRIMARY], 2))
408
+ >>> set_delta_nfr_hook(G, spawn)
409
+ >>> run_sequence(G, node, [SelfOrganization()])
410
+ >>> G.graph["sub_epi"]
411
+ [0.7]
412
+ """
413
+
414
+ __slots__ = ()
415
+ name: ClassVar[str] = SELF_ORGANIZATION
416
+ glyph: ClassVar[Glyph] = Glyph.THOL
417
+
418
+
419
+ @register_operator
420
+ class Mutation(Operator):
421
+ """Recode phase or form so the node can cross structural thresholds.
422
+
423
+ Activates glyph ``ZHIR`` to pivot the node towards a new coherence regime.
424
+
425
+ Examples
426
+ --------
427
+ >>> from tnfr.constants import EPI_PRIMARY, THETA_PRIMARY
428
+ >>> from tnfr.dynamics import set_delta_nfr_hook
429
+ >>> from tnfr.structural import create_nfr, run_sequence
430
+ >>> from tnfr.operators.definitions import Mutation
431
+ >>> G, node = create_nfr("lambda", epi=0.73, theta=0.20)
432
+ >>> shifts = iter([(0.03, 0.40)])
433
+ >>> def mutate(graph):
434
+ ... d_epi, d_theta = next(shifts)
435
+ ... graph.nodes[node][EPI_PRIMARY] += d_epi
436
+ ... graph.nodes[node][THETA_PRIMARY] += d_theta
437
+ >>> set_delta_nfr_hook(G, mutate)
438
+ >>> run_sequence(G, node, [Mutation()])
439
+ >>> round(G.nodes[node][EPI_PRIMARY], 2)
440
+ 0.76
441
+ >>> round(G.nodes[node][THETA_PRIMARY], 2)
442
+ 0.6
443
+ """
444
+
445
+ __slots__ = ()
446
+ name: ClassVar[str] = MUTATION
447
+ glyph: ClassVar[Glyph] = Glyph.ZHIR
448
+
449
+
450
+ @register_operator
451
+ class Transition(Operator):
452
+ """Guide the node through a controlled transition between regimes.
453
+
454
+ Activates glyph ``NAV`` to manage hand-offs across structural states.
455
+
456
+ Examples
457
+ --------
458
+ >>> from tnfr.constants import DNFR_PRIMARY, THETA_PRIMARY, VF_PRIMARY
459
+ >>> from tnfr.dynamics import set_delta_nfr_hook
460
+ >>> from tnfr.structural import create_nfr, run_sequence
461
+ >>> from tnfr.operators.definitions import Transition
462
+ >>> G, node = create_nfr("mu", vf=0.85, theta=0.40)
463
+ >>> ramps = iter([(0.12, -0.25)])
464
+ >>> def handoff(graph):
465
+ ... d_vf, d_theta = next(ramps)
466
+ ... graph.nodes[node][VF_PRIMARY] += d_vf
467
+ ... graph.nodes[node][THETA_PRIMARY] += d_theta
468
+ ... graph.nodes[node][DNFR_PRIMARY] = abs(d_vf) * 0.5
469
+ >>> set_delta_nfr_hook(G, handoff)
470
+ >>> run_sequence(G, node, [Transition()])
471
+ >>> round(G.nodes[node][VF_PRIMARY], 2)
472
+ 0.97
473
+ >>> round(G.nodes[node][THETA_PRIMARY], 2)
474
+ 0.15
475
+ >>> round(G.nodes[node][DNFR_PRIMARY], 2)
476
+ 0.06
477
+ """
478
+
479
+ __slots__ = ()
480
+ name: ClassVar[str] = TRANSITION
481
+ glyph: ClassVar[Glyph] = Glyph.NAV
482
+
483
+
484
+ @register_operator
485
+ class Recursivity(Operator):
486
+ """Propagate fractal recursivity to maintain multi-scale identity.
487
+
488
+ Activates glyph ``REMESH`` to echo structural patterns across nested EPIs.
489
+
490
+ Examples
491
+ --------
492
+ >>> from tnfr.constants import EPI_PRIMARY, VF_PRIMARY
493
+ >>> from tnfr.dynamics import set_delta_nfr_hook
494
+ >>> from tnfr.structural import create_nfr, run_sequence
495
+ >>> from tnfr.operators.definitions import Recursivity
496
+ >>> G, node = create_nfr("nu", epi=0.52, vf=0.92)
497
+ >>> echoes = iter([(0.02, 0.03)])
498
+ >>> def echo(graph):
499
+ ... d_epi, d_vf = next(echoes)
500
+ ... graph.nodes[node][EPI_PRIMARY] += d_epi
501
+ ... graph.nodes[node][VF_PRIMARY] += d_vf
502
+ ... graph.graph.setdefault("echo_trace", []).append(
503
+ ... (round(graph.nodes[node][EPI_PRIMARY], 2), round(graph.nodes[node][VF_PRIMARY], 2))
504
+ ... )
505
+ >>> set_delta_nfr_hook(G, echo)
506
+ >>> run_sequence(G, node, [Recursivity()])
507
+ >>> G.graph["echo_trace"]
508
+ [(0.54, 0.95)]
509
+ """
510
+
511
+ __slots__ = ()
512
+ name: ClassVar[str] = RECURSIVITY
513
+ glyph: ClassVar[Glyph] = Glyph.REMESH
@@ -0,0 +1,78 @@
1
+ from typing import Any, ClassVar
2
+
3
+ from ..types import Glyph, TNFRGraph
4
+
5
+ __all__ = (
6
+ "Operator",
7
+ "Emission",
8
+ "Reception",
9
+ "Coherence",
10
+ "Dissonance",
11
+ "Coupling",
12
+ "Resonance",
13
+ "Silence",
14
+ "Expansion",
15
+ "Contraction",
16
+ "SelfOrganization",
17
+ "Mutation",
18
+ "Transition",
19
+ "Recursivity",
20
+ )
21
+
22
+ class Operator:
23
+ name: ClassVar[str]
24
+ glyph: ClassVar[Glyph | None]
25
+
26
+ def __call__(self, G: TNFRGraph, node: Any, **kw: Any) -> None: ...
27
+
28
+ class Emission(Operator):
29
+ name: ClassVar[str]
30
+ glyph: ClassVar[Glyph]
31
+
32
+ class Reception(Operator):
33
+ name: ClassVar[str]
34
+ glyph: ClassVar[Glyph]
35
+
36
+ class Coherence(Operator):
37
+ name: ClassVar[str]
38
+ glyph: ClassVar[Glyph]
39
+
40
+ class Dissonance(Operator):
41
+ name: ClassVar[str]
42
+ glyph: ClassVar[Glyph]
43
+
44
+ class Coupling(Operator):
45
+ name: ClassVar[str]
46
+ glyph: ClassVar[Glyph]
47
+
48
+ class Resonance(Operator):
49
+ name: ClassVar[str]
50
+ glyph: ClassVar[Glyph]
51
+
52
+ class Silence(Operator):
53
+ name: ClassVar[str]
54
+ glyph: ClassVar[Glyph]
55
+
56
+ class Expansion(Operator):
57
+ name: ClassVar[str]
58
+ glyph: ClassVar[Glyph]
59
+
60
+ class Contraction(Operator):
61
+ name: ClassVar[str]
62
+ glyph: ClassVar[Glyph]
63
+
64
+ class SelfOrganization(Operator):
65
+ name: ClassVar[str]
66
+ glyph: ClassVar[Glyph]
67
+
68
+ class Mutation(Operator):
69
+ name: ClassVar[str]
70
+ glyph: ClassVar[Glyph]
71
+
72
+ class Transition(Operator):
73
+ name: ClassVar[str]
74
+ glyph: ClassVar[Glyph]
75
+
76
+ class Recursivity(Operator):
77
+ name: ClassVar[str]
78
+ glyph: ClassVar[Glyph]