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
@@ -18,14 +18,28 @@ GLYPH_OPERATIONS: Any
18
18
  JitterCache: Any
19
19
  JitterCacheManager: Any
20
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
21
30
  apply_glyph: Any
22
31
  apply_glyph_obj: Any
32
+ apply_glyph_with_grammar: Any
23
33
  apply_network_remesh: Any
24
34
  apply_remesh_if_globally_stable: Any
25
35
  apply_topological_remesh: Any
26
36
  discover_operators: Any
37
+ enforce_canonical_grammar: Any
27
38
  get_glyph_factors: Any
28
39
  get_jitter_manager: Any
29
40
  get_neighbor_epi: Any
41
+ on_applied_glyph: Any
42
+ parse_sequence: Any
30
43
  random_jitter: Any
31
44
  reset_jitter_manager: Any
45
+ validate_sequence: Any
@@ -10,9 +10,11 @@ from typing import Any, ClassVar
10
10
 
11
11
  from ..config.operator_names import (
12
12
  COHERENCE,
13
+ CONTRACTION,
13
14
  COUPLING,
14
15
  DISSONANCE,
15
16
  EMISSION,
17
+ EXPANSION,
16
18
  MUTATION,
17
19
  RECEPTION,
18
20
  RECURSIVITY,
@@ -20,8 +22,6 @@ from ..config.operator_names import (
20
22
  SELF_ORGANIZATION,
21
23
  SILENCE,
22
24
  TRANSITION,
23
- CONTRACTION,
24
- EXPANSION,
25
25
  )
26
26
  from ..types import Glyph, TNFRGraph
27
27
  from .registry import register_operator
@@ -55,18 +55,68 @@ class Operator:
55
55
  glyph: ClassVar[Glyph | None] = None
56
56
 
57
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
+ """
58
86
  if self.glyph is None:
59
87
  raise NotImplementedError("Operator without assigned glyph")
60
- from ..validation.grammar import ( # local import to avoid cycles
61
- apply_glyph_with_grammar,
62
- )
88
+ from . import apply_glyph_with_grammar
63
89
 
64
90
  apply_glyph_with_grammar(G, [node], self.glyph, kw.get("window"))
65
91
 
66
92
 
67
93
  @register_operator
68
94
  class Emission(Operator):
69
- """Emission operator (glyph ``AL``)."""
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
+ """
70
120
 
71
121
  __slots__ = ()
72
122
  name: ClassVar[str] = EMISSION
@@ -75,7 +125,30 @@ class Emission(Operator):
75
125
 
76
126
  @register_operator
77
127
  class Reception(Operator):
78
- """Reception operator (glyph ``EN``)."""
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
+ """
79
152
 
80
153
  __slots__ = ()
81
154
  name: ClassVar[str] = RECEPTION
@@ -84,7 +157,33 @@ class Reception(Operator):
84
157
 
85
158
  @register_operator
86
159
  class Coherence(Operator):
87
- """Coherence operator (glyph ``IL``)."""
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
+ """
88
187
 
89
188
  __slots__ = ()
90
189
  name: ClassVar[str] = COHERENCE
@@ -93,7 +192,30 @@ class Coherence(Operator):
93
192
 
94
193
  @register_operator
95
194
  class Dissonance(Operator):
96
- """Dissonance operator (glyph ``OZ``)."""
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
+ """
97
219
 
98
220
  __slots__ = ()
99
221
  name: ClassVar[str] = DISSONANCE
@@ -102,7 +224,32 @@ class Dissonance(Operator):
102
224
 
103
225
  @register_operator
104
226
  class Coupling(Operator):
105
- """Coupling operator (glyph ``UM``)."""
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
+ """
106
253
 
107
254
  __slots__ = ()
108
255
  name: ClassVar[str] = COUPLING
@@ -111,7 +258,30 @@ class Coupling(Operator):
111
258
 
112
259
  @register_operator
113
260
  class Resonance(Operator):
114
- """Resonance operator (glyph ``RA``)."""
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
+ """
115
285
 
116
286
  __slots__ = ()
117
287
  name: ClassVar[str] = RESONANCE
@@ -120,7 +290,28 @@ class Resonance(Operator):
120
290
 
121
291
  @register_operator
122
292
  class Silence(Operator):
123
- """Silence operator (glyph ``SHA``)."""
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
+ """
124
315
 
125
316
  __slots__ = ()
126
317
  name: ClassVar[str] = SILENCE
@@ -129,7 +320,30 @@ class Silence(Operator):
129
320
 
130
321
  @register_operator
131
322
  class Expansion(Operator):
132
- """Expansion operator (glyph ``VAL``)."""
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
+ """
133
347
 
134
348
  __slots__ = ()
135
349
  name: ClassVar[str] = EXPANSION
@@ -138,7 +352,33 @@ class Expansion(Operator):
138
352
 
139
353
  @register_operator
140
354
  class Contraction(Operator):
141
- """Contraction operator (glyph ``NUL``)."""
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
+ """
142
382
 
143
383
  __slots__ = ()
144
384
  name: ClassVar[str] = CONTRACTION
@@ -147,7 +387,29 @@ class Contraction(Operator):
147
387
 
148
388
  @register_operator
149
389
  class SelfOrganization(Operator):
150
- """Self-organization operator (glyph ``THOL``)."""
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
+ """
151
413
 
152
414
  __slots__ = ()
153
415
  name: ClassVar[str] = SELF_ORGANIZATION
@@ -156,7 +418,29 @@ class SelfOrganization(Operator):
156
418
 
157
419
  @register_operator
158
420
  class Mutation(Operator):
159
- """Mutation operator (glyph ``ZHIR``)."""
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
+ """
160
444
 
161
445
  __slots__ = ()
162
446
  name: ClassVar[str] = MUTATION
@@ -165,7 +449,32 @@ class Mutation(Operator):
165
449
 
166
450
  @register_operator
167
451
  class Transition(Operator):
168
- """Transition operator (glyph ``NAV``)."""
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
+ """
169
478
 
170
479
  __slots__ = ()
171
480
  name: ClassVar[str] = TRANSITION
@@ -174,7 +483,30 @@ class Transition(Operator):
174
483
 
175
484
  @register_operator
176
485
  class Recursivity(Operator):
177
- """Recursivity operator (glyph ``REMESH``)."""
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
+ """
178
510
 
179
511
  __slots__ = ()
180
512
  name: ClassVar[str] = RECURSIVITY
@@ -19,74 +19,60 @@ __all__ = (
19
19
  "Recursivity",
20
20
  )
21
21
 
22
-
23
22
  class Operator:
24
23
  name: ClassVar[str]
25
24
  glyph: ClassVar[Glyph | None]
26
25
 
27
26
  def __call__(self, G: TNFRGraph, node: Any, **kw: Any) -> None: ...
28
27
 
29
-
30
28
  class Emission(Operator):
31
29
  name: ClassVar[str]
32
30
  glyph: ClassVar[Glyph]
33
31
 
34
-
35
32
  class Reception(Operator):
36
33
  name: ClassVar[str]
37
34
  glyph: ClassVar[Glyph]
38
35
 
39
-
40
36
  class Coherence(Operator):
41
37
  name: ClassVar[str]
42
38
  glyph: ClassVar[Glyph]
43
39
 
44
-
45
40
  class Dissonance(Operator):
46
41
  name: ClassVar[str]
47
42
  glyph: ClassVar[Glyph]
48
43
 
49
-
50
44
  class Coupling(Operator):
51
45
  name: ClassVar[str]
52
46
  glyph: ClassVar[Glyph]
53
47
 
54
-
55
48
  class Resonance(Operator):
56
49
  name: ClassVar[str]
57
50
  glyph: ClassVar[Glyph]
58
51
 
59
-
60
52
  class Silence(Operator):
61
53
  name: ClassVar[str]
62
54
  glyph: ClassVar[Glyph]
63
55
 
64
-
65
56
  class Expansion(Operator):
66
57
  name: ClassVar[str]
67
58
  glyph: ClassVar[Glyph]
68
59
 
69
-
70
60
  class Contraction(Operator):
71
61
  name: ClassVar[str]
72
62
  glyph: ClassVar[Glyph]
73
63
 
74
-
75
64
  class SelfOrganization(Operator):
76
65
  name: ClassVar[str]
77
66
  glyph: ClassVar[Glyph]
78
67
 
79
-
80
68
  class Mutation(Operator):
81
69
  name: ClassVar[str]
82
70
  glyph: ClassVar[Glyph]
83
71
 
84
-
85
72
  class Transition(Operator):
86
73
  name: ClassVar[str]
87
74
  glyph: ClassVar[Glyph]
88
75
 
89
-
90
76
  class Recursivity(Operator):
91
77
  name: ClassVar[str]
92
78
  glyph: ClassVar[Glyph]