tnfr 4.5.2__py3-none-any.whl → 6.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tnfr/__init__.py +228 -49
- tnfr/__init__.pyi +40 -0
- tnfr/_compat.py +11 -0
- tnfr/_version.py +7 -0
- tnfr/_version.pyi +7 -0
- tnfr/alias.py +106 -21
- tnfr/alias.pyi +140 -0
- tnfr/cache.py +666 -512
- tnfr/cache.pyi +232 -0
- tnfr/callback_utils.py +2 -9
- tnfr/callback_utils.pyi +105 -0
- tnfr/cli/__init__.py +21 -7
- tnfr/cli/__init__.pyi +47 -0
- tnfr/cli/arguments.py +42 -20
- tnfr/cli/arguments.pyi +33 -0
- tnfr/cli/execution.py +54 -20
- tnfr/cli/execution.pyi +80 -0
- tnfr/cli/utils.py +0 -2
- tnfr/cli/utils.pyi +8 -0
- tnfr/config/__init__.py +12 -0
- tnfr/config/__init__.pyi +8 -0
- tnfr/config/constants.py +104 -0
- tnfr/config/constants.pyi +12 -0
- tnfr/{config.py → config/init.py} +11 -7
- tnfr/config/init.pyi +8 -0
- tnfr/config/operator_names.py +106 -0
- tnfr/config/operator_names.pyi +28 -0
- tnfr/config/presets.py +104 -0
- tnfr/config/presets.pyi +7 -0
- tnfr/constants/__init__.py +78 -24
- tnfr/constants/__init__.pyi +104 -0
- tnfr/constants/core.py +1 -2
- tnfr/constants/core.pyi +17 -0
- tnfr/constants/init.pyi +12 -0
- tnfr/constants/metric.py +4 -12
- tnfr/constants/metric.pyi +19 -0
- tnfr/constants_glyphs.py +9 -91
- tnfr/constants_glyphs.pyi +12 -0
- tnfr/dynamics/__init__.py +112 -634
- tnfr/dynamics/__init__.pyi +83 -0
- tnfr/dynamics/adaptation.py +201 -0
- tnfr/dynamics/aliases.py +22 -0
- tnfr/dynamics/coordination.py +343 -0
- tnfr/dynamics/dnfr.py +1936 -354
- tnfr/dynamics/dnfr.pyi +33 -0
- tnfr/dynamics/integrators.py +369 -75
- tnfr/dynamics/integrators.pyi +35 -0
- tnfr/dynamics/runtime.py +521 -0
- tnfr/dynamics/sampling.py +8 -5
- tnfr/dynamics/sampling.pyi +7 -0
- tnfr/dynamics/selectors.py +680 -0
- tnfr/execution.py +56 -41
- tnfr/execution.pyi +65 -0
- tnfr/flatten.py +7 -7
- tnfr/flatten.pyi +28 -0
- tnfr/gamma.py +54 -37
- tnfr/gamma.pyi +40 -0
- tnfr/glyph_history.py +85 -38
- tnfr/glyph_history.pyi +53 -0
- tnfr/grammar.py +19 -338
- tnfr/grammar.pyi +13 -0
- tnfr/helpers/__init__.py +110 -30
- tnfr/helpers/__init__.pyi +66 -0
- tnfr/helpers/numeric.py +1 -0
- tnfr/helpers/numeric.pyi +12 -0
- tnfr/immutable.py +55 -19
- tnfr/immutable.pyi +37 -0
- tnfr/initialization.py +12 -10
- tnfr/initialization.pyi +73 -0
- tnfr/io.py +99 -34
- tnfr/io.pyi +11 -0
- tnfr/locking.pyi +7 -0
- tnfr/metrics/__init__.pyi +20 -0
- tnfr/metrics/coherence.py +934 -294
- tnfr/metrics/common.py +1 -3
- tnfr/metrics/common.pyi +15 -0
- tnfr/metrics/core.py +192 -34
- tnfr/metrics/core.pyi +13 -0
- tnfr/metrics/diagnosis.py +707 -101
- tnfr/metrics/diagnosis.pyi +89 -0
- tnfr/metrics/export.py +27 -13
- tnfr/metrics/glyph_timing.py +218 -38
- tnfr/metrics/reporting.py +22 -18
- tnfr/metrics/reporting.pyi +12 -0
- tnfr/metrics/sense_index.py +199 -25
- tnfr/metrics/sense_index.pyi +9 -0
- tnfr/metrics/trig.py +53 -18
- tnfr/metrics/trig.pyi +12 -0
- tnfr/metrics/trig_cache.py +3 -7
- tnfr/metrics/trig_cache.pyi +10 -0
- tnfr/node.py +148 -125
- tnfr/node.pyi +161 -0
- tnfr/observers.py +44 -30
- tnfr/observers.pyi +46 -0
- tnfr/ontosim.py +14 -13
- tnfr/ontosim.pyi +33 -0
- tnfr/operators/__init__.py +84 -52
- tnfr/operators/__init__.pyi +31 -0
- tnfr/operators/definitions.py +181 -0
- tnfr/operators/definitions.pyi +92 -0
- tnfr/operators/jitter.py +86 -23
- tnfr/operators/jitter.pyi +11 -0
- tnfr/operators/registry.py +80 -0
- tnfr/operators/registry.pyi +15 -0
- tnfr/operators/remesh.py +141 -57
- tnfr/presets.py +9 -54
- tnfr/presets.pyi +7 -0
- tnfr/py.typed +0 -0
- tnfr/rng.py +259 -73
- tnfr/rng.pyi +14 -0
- tnfr/selector.py +24 -17
- tnfr/selector.pyi +19 -0
- tnfr/sense.py +55 -43
- tnfr/sense.pyi +30 -0
- tnfr/structural.py +44 -267
- tnfr/structural.pyi +46 -0
- tnfr/telemetry/__init__.py +13 -0
- tnfr/telemetry/verbosity.py +37 -0
- tnfr/tokens.py +3 -2
- tnfr/tokens.pyi +41 -0
- tnfr/trace.py +272 -82
- tnfr/trace.pyi +68 -0
- tnfr/types.py +345 -6
- tnfr/types.pyi +145 -0
- tnfr/utils/__init__.py +158 -0
- tnfr/utils/__init__.pyi +133 -0
- tnfr/utils/cache.py +755 -0
- tnfr/utils/cache.pyi +156 -0
- tnfr/{collections_utils.py → utils/data.py} +57 -90
- tnfr/utils/data.pyi +73 -0
- tnfr/utils/graph.py +87 -0
- tnfr/utils/graph.pyi +10 -0
- tnfr/utils/init.py +746 -0
- tnfr/utils/init.pyi +85 -0
- tnfr/{json_utils.py → utils/io.py} +13 -18
- tnfr/utils/io.pyi +10 -0
- tnfr/utils/validators.py +130 -0
- tnfr/utils/validators.pyi +19 -0
- tnfr/validation/__init__.py +25 -0
- tnfr/validation/__init__.pyi +17 -0
- tnfr/validation/compatibility.py +59 -0
- tnfr/validation/compatibility.pyi +8 -0
- tnfr/validation/grammar.py +149 -0
- tnfr/validation/grammar.pyi +11 -0
- tnfr/validation/rules.py +194 -0
- tnfr/validation/rules.pyi +18 -0
- tnfr/validation/syntax.py +151 -0
- tnfr/validation/syntax.pyi +7 -0
- tnfr-6.0.0.dist-info/METADATA +135 -0
- tnfr-6.0.0.dist-info/RECORD +157 -0
- tnfr/graph_utils.py +0 -84
- tnfr/import_utils.py +0 -228
- tnfr/logging_utils.py +0 -116
- tnfr/validators.py +0 -84
- tnfr/value_utils.py +0 -59
- tnfr-4.5.2.dist-info/METADATA +0 -379
- tnfr-4.5.2.dist-info/RECORD +0 -67
- {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/WHEEL +0 -0
- {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/entry_points.txt +0 -0
- {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/licenses/LICENSE.md +0 -0
- {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/top_level.txt +0 -0
tnfr/validation/rules.py
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Validation helpers grouped by rule type.
|
|
2
|
+
|
|
3
|
+
These utilities implement the canonical checks required by
|
|
4
|
+
:mod:`tnfr.validation.grammar`. They are organised here to make it
|
|
5
|
+
explicit which pieces enforce repetition control, transition
|
|
6
|
+
compatibility or stabilisation thresholds.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from typing import Any, Callable, Mapping, TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
from ..alias import get_attr
|
|
14
|
+
from ..constants import get_aliases
|
|
15
|
+
from ..glyph_history import recent_glyph
|
|
16
|
+
from ..helpers.numeric import clamp01
|
|
17
|
+
from ..metrics.common import normalize_dnfr
|
|
18
|
+
from ..types import Glyph
|
|
19
|
+
from .compatibility import CANON_COMPAT, CANON_FALLBACK
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING: # pragma: no cover - only for typing
|
|
22
|
+
from .grammar import GrammarContext
|
|
23
|
+
|
|
24
|
+
ALIAS_SI = get_aliases("SI")
|
|
25
|
+
ALIAS_D2EPI = get_aliases("D2EPI")
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
"coerce_glyph",
|
|
29
|
+
"glyph_fallback",
|
|
30
|
+
"get_norm",
|
|
31
|
+
"normalized_dnfr",
|
|
32
|
+
"_norm_attr",
|
|
33
|
+
"_si",
|
|
34
|
+
"_accel_norm",
|
|
35
|
+
"_check_repeats",
|
|
36
|
+
"_maybe_force",
|
|
37
|
+
"_check_oz_to_zhir",
|
|
38
|
+
"_check_thol_closure",
|
|
39
|
+
"_check_compatibility",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def coerce_glyph(val: Any) -> Glyph | Any:
|
|
44
|
+
"""Return ``val`` coerced to :class:`Glyph` when possible."""
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
return Glyph(val)
|
|
48
|
+
except (ValueError, TypeError):
|
|
49
|
+
return val
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def glyph_fallback(cand_key: str, fallbacks: Mapping[str, Any]) -> Glyph | str:
|
|
53
|
+
"""Determine fallback glyph for ``cand_key`` considering canon tables."""
|
|
54
|
+
|
|
55
|
+
glyph_key = coerce_glyph(cand_key)
|
|
56
|
+
canon_fb = (
|
|
57
|
+
CANON_FALLBACK.get(glyph_key, cand_key)
|
|
58
|
+
if isinstance(glyph_key, Glyph)
|
|
59
|
+
else cand_key
|
|
60
|
+
)
|
|
61
|
+
fb = fallbacks.get(cand_key, canon_fb)
|
|
62
|
+
return coerce_glyph(fb)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# -------------------------
|
|
66
|
+
# Normalisation helpers
|
|
67
|
+
# -------------------------
|
|
68
|
+
|
|
69
|
+
def get_norm(ctx: "GrammarContext", key: str) -> float:
|
|
70
|
+
"""Retrieve a global normalisation value from ``ctx.norms``."""
|
|
71
|
+
|
|
72
|
+
return float(ctx.norms.get(key, 1.0)) or 1.0
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _norm_attr(ctx: "GrammarContext", nd, attr_alias: str, norm_key: str) -> float:
|
|
76
|
+
"""Normalise ``attr_alias`` using the global maximum ``norm_key``."""
|
|
77
|
+
|
|
78
|
+
max_val = get_norm(ctx, norm_key)
|
|
79
|
+
return clamp01(abs(get_attr(nd, attr_alias, 0.0)) / max_val)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _si(nd) -> float:
|
|
83
|
+
"""Return the structural sense index for ``nd`` clamped to ``[0, 1]``."""
|
|
84
|
+
|
|
85
|
+
return clamp01(get_attr(nd, ALIAS_SI, 0.5))
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _accel_norm(ctx: "GrammarContext", nd) -> float:
|
|
89
|
+
"""Normalise acceleration using the global maximum."""
|
|
90
|
+
|
|
91
|
+
return _norm_attr(ctx, nd, ALIAS_D2EPI, "accel_max")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def normalized_dnfr(ctx: "GrammarContext", nd) -> float:
|
|
95
|
+
"""Normalise |ΔNFR| using the configured global maximum."""
|
|
96
|
+
|
|
97
|
+
return normalize_dnfr(nd, get_norm(ctx, "dnfr_max"))
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# -------------------------
|
|
101
|
+
# Validation rules
|
|
102
|
+
# -------------------------
|
|
103
|
+
|
|
104
|
+
def _check_repeats(ctx: "GrammarContext", n, cand: Glyph | str) -> Glyph | str:
|
|
105
|
+
"""Avoid recent repetitions according to ``ctx.cfg_soft``."""
|
|
106
|
+
|
|
107
|
+
nd = ctx.G.nodes[n]
|
|
108
|
+
cfg = ctx.cfg_soft
|
|
109
|
+
gwin = int(cfg.get("window", 0))
|
|
110
|
+
avoid = set(cfg.get("avoid_repeats", []))
|
|
111
|
+
fallbacks = cfg.get("fallbacks", {})
|
|
112
|
+
cand_key = cand.value if isinstance(cand, Glyph) else str(cand)
|
|
113
|
+
if gwin > 0 and cand_key in avoid and recent_glyph(nd, cand_key, gwin):
|
|
114
|
+
return glyph_fallback(cand_key, fallbacks)
|
|
115
|
+
return cand
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _maybe_force(
|
|
119
|
+
ctx: "GrammarContext",
|
|
120
|
+
n,
|
|
121
|
+
cand: Glyph | str,
|
|
122
|
+
original: Glyph | str,
|
|
123
|
+
accessor: Callable[["GrammarContext", dict[str, Any]], float],
|
|
124
|
+
key: str,
|
|
125
|
+
) -> Glyph | str:
|
|
126
|
+
"""Restore ``original`` if ``accessor`` exceeds ``key`` threshold."""
|
|
127
|
+
|
|
128
|
+
if cand == original:
|
|
129
|
+
return cand
|
|
130
|
+
force_th = float(ctx.cfg_soft.get(key, 0.60))
|
|
131
|
+
if accessor(ctx, ctx.G.nodes[n]) >= force_th:
|
|
132
|
+
return original
|
|
133
|
+
return cand
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _check_oz_to_zhir(ctx: "GrammarContext", n, cand: Glyph | str) -> Glyph | str:
|
|
137
|
+
"""Enforce OZ precedents before allowing ZHIR mutations."""
|
|
138
|
+
|
|
139
|
+
nd = ctx.G.nodes[n]
|
|
140
|
+
cand_glyph = coerce_glyph(cand)
|
|
141
|
+
if cand_glyph == Glyph.ZHIR:
|
|
142
|
+
cfg = ctx.cfg_canon
|
|
143
|
+
win = int(cfg.get("zhir_requires_oz_window", 3))
|
|
144
|
+
dn_min = float(cfg.get("zhir_dnfr_min", 0.05))
|
|
145
|
+
if (
|
|
146
|
+
not recent_glyph(nd, Glyph.OZ, win)
|
|
147
|
+
and normalized_dnfr(ctx, nd) < dn_min
|
|
148
|
+
):
|
|
149
|
+
return Glyph.OZ
|
|
150
|
+
return cand
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _check_thol_closure(
|
|
154
|
+
ctx: "GrammarContext", n, cand: Glyph | str, st: dict[str, Any]
|
|
155
|
+
) -> Glyph | str:
|
|
156
|
+
"""Close THOL blocks with canonical glyphs once stabilised."""
|
|
157
|
+
|
|
158
|
+
nd = ctx.G.nodes[n]
|
|
159
|
+
if st.get("thol_open", False):
|
|
160
|
+
st["thol_len"] = int(st.get("thol_len", 0)) + 1
|
|
161
|
+
cfg = ctx.cfg_canon
|
|
162
|
+
minlen = int(cfg.get("thol_min_len", 2))
|
|
163
|
+
maxlen = int(cfg.get("thol_max_len", 6))
|
|
164
|
+
close_dn = float(cfg.get("thol_close_dnfr", 0.15))
|
|
165
|
+
if st["thol_len"] >= maxlen or (
|
|
166
|
+
st["thol_len"] >= minlen
|
|
167
|
+
and normalized_dnfr(ctx, nd) <= close_dn
|
|
168
|
+
):
|
|
169
|
+
return (
|
|
170
|
+
Glyph.NUL
|
|
171
|
+
if _si(nd) >= float(cfg.get("si_high", 0.66))
|
|
172
|
+
else Glyph.SHA
|
|
173
|
+
)
|
|
174
|
+
return cand
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _check_compatibility(ctx: "GrammarContext", n, cand: Glyph | str) -> Glyph | str:
|
|
178
|
+
"""Verify canonical transition compatibility for ``cand``."""
|
|
179
|
+
|
|
180
|
+
nd = ctx.G.nodes[n]
|
|
181
|
+
hist = nd.get("glyph_history")
|
|
182
|
+
prev = hist[-1] if hist else None
|
|
183
|
+
prev_glyph = coerce_glyph(prev)
|
|
184
|
+
cand_glyph = coerce_glyph(cand)
|
|
185
|
+
if isinstance(prev_glyph, Glyph):
|
|
186
|
+
allowed = CANON_COMPAT.get(prev_glyph)
|
|
187
|
+
if allowed is None:
|
|
188
|
+
return cand
|
|
189
|
+
if isinstance(cand_glyph, Glyph):
|
|
190
|
+
if cand_glyph not in allowed:
|
|
191
|
+
return CANON_FALLBACK.get(prev_glyph, cand_glyph)
|
|
192
|
+
else:
|
|
193
|
+
return CANON_FALLBACK.get(prev_glyph, cand)
|
|
194
|
+
return cand
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
__all__: Any
|
|
4
|
+
|
|
5
|
+
def __getattr__(name: str) -> Any: ...
|
|
6
|
+
|
|
7
|
+
_accel_norm: Any
|
|
8
|
+
_check_compatibility: Any
|
|
9
|
+
_check_oz_to_zhir: Any
|
|
10
|
+
_check_repeats: Any
|
|
11
|
+
_check_thol_closure: Any
|
|
12
|
+
_maybe_force: Any
|
|
13
|
+
_norm_attr: Any
|
|
14
|
+
_si: Any
|
|
15
|
+
coerce_glyph: Any
|
|
16
|
+
get_norm: Any
|
|
17
|
+
glyph_fallback: Any
|
|
18
|
+
normalized_dnfr: Any
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"""Syntax validation for TNFR operator sequences."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterable
|
|
6
|
+
|
|
7
|
+
from ..operators.registry import OPERATORS
|
|
8
|
+
from ..config.operator_names import (
|
|
9
|
+
COHERENCE,
|
|
10
|
+
INTERMEDIATE_OPERATORS,
|
|
11
|
+
RECEPTION,
|
|
12
|
+
SELF_ORGANIZATION,
|
|
13
|
+
SELF_ORGANIZATION_CLOSURES,
|
|
14
|
+
VALID_END_OPERATORS,
|
|
15
|
+
VALID_START_OPERATORS,
|
|
16
|
+
canonical_operator_name,
|
|
17
|
+
operator_display_name,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
__all__ = ("validate_sequence",)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
_MISSING = object()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
_CANONICAL_START = tuple(sorted(VALID_START_OPERATORS))
|
|
27
|
+
_CANONICAL_INTERMEDIATE = tuple(sorted(INTERMEDIATE_OPERATORS))
|
|
28
|
+
_CANONICAL_END = tuple(sorted(VALID_END_OPERATORS))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _format_token_group(tokens: tuple[str, ...]) -> str:
|
|
32
|
+
return ", ".join(operator_display_name(token) for token in sorted(tokens))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _validate_start(token: str) -> tuple[bool, str]:
|
|
36
|
+
"""Ensure the sequence begins with a valid structural operator."""
|
|
37
|
+
|
|
38
|
+
if not isinstance(token, str):
|
|
39
|
+
return False, "tokens must be str"
|
|
40
|
+
if token not in VALID_START_OPERATORS:
|
|
41
|
+
valid_tokens = _format_token_group(_CANONICAL_START)
|
|
42
|
+
return False, f"must start with {valid_tokens}"
|
|
43
|
+
return True, ""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _validate_intermediate(
|
|
47
|
+
found_reception: bool, found_coherence: bool, seen_intermediate: bool
|
|
48
|
+
) -> tuple[bool, str]:
|
|
49
|
+
"""Check that the central TNFR segment is present."""
|
|
50
|
+
|
|
51
|
+
if not (found_reception and found_coherence):
|
|
52
|
+
return False, f"missing {RECEPTION}→{COHERENCE} segment"
|
|
53
|
+
if not seen_intermediate:
|
|
54
|
+
intermediate_tokens = _format_token_group(_CANONICAL_INTERMEDIATE)
|
|
55
|
+
return False, f"missing {intermediate_tokens} segment"
|
|
56
|
+
return True, ""
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _validate_end(last_token: str, open_thol: bool) -> tuple[bool, str]:
|
|
60
|
+
"""Validate closing operator and any pending THOL blocks."""
|
|
61
|
+
|
|
62
|
+
if last_token not in VALID_END_OPERATORS:
|
|
63
|
+
cierre_tokens = _format_token_group(_CANONICAL_END)
|
|
64
|
+
return False, f"sequence must end with {cierre_tokens}"
|
|
65
|
+
if open_thol:
|
|
66
|
+
return False, "THOL block without closure"
|
|
67
|
+
return True, ""
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _validate_known_tokens(
|
|
71
|
+
token_to_canonical: dict[str, str]
|
|
72
|
+
) -> tuple[bool, str]:
|
|
73
|
+
"""Ensure all tokens map to canonical operators."""
|
|
74
|
+
|
|
75
|
+
unknown_tokens = {
|
|
76
|
+
alias
|
|
77
|
+
for alias, canonical in token_to_canonical.items()
|
|
78
|
+
if canonical not in OPERATORS
|
|
79
|
+
}
|
|
80
|
+
if unknown_tokens:
|
|
81
|
+
ordered = ", ".join(sorted(unknown_tokens))
|
|
82
|
+
return False, f"unknown tokens: {ordered}"
|
|
83
|
+
return True, ""
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _validate_token_sequence(names: list[str]) -> tuple[bool, str]:
|
|
87
|
+
"""Validate token format and logical coherence in one pass."""
|
|
88
|
+
|
|
89
|
+
if not names:
|
|
90
|
+
return False, "empty sequence"
|
|
91
|
+
|
|
92
|
+
ok, msg = _validate_start(names[0])
|
|
93
|
+
if not ok:
|
|
94
|
+
return False, msg
|
|
95
|
+
|
|
96
|
+
token_to_canonical: dict[str, str] = {}
|
|
97
|
+
found_reception = False
|
|
98
|
+
found_coherence = False
|
|
99
|
+
seen_intermediate = False
|
|
100
|
+
open_thol = False
|
|
101
|
+
|
|
102
|
+
for name in names:
|
|
103
|
+
if not isinstance(name, str):
|
|
104
|
+
return False, "tokens must be str"
|
|
105
|
+
canonical = canonical_operator_name(name)
|
|
106
|
+
token_to_canonical[name] = canonical
|
|
107
|
+
|
|
108
|
+
if canonical == RECEPTION and not found_reception:
|
|
109
|
+
found_reception = True
|
|
110
|
+
elif found_reception and canonical == COHERENCE and not found_coherence:
|
|
111
|
+
found_coherence = True
|
|
112
|
+
elif (
|
|
113
|
+
found_coherence
|
|
114
|
+
and not seen_intermediate
|
|
115
|
+
and canonical in INTERMEDIATE_OPERATORS
|
|
116
|
+
):
|
|
117
|
+
seen_intermediate = True
|
|
118
|
+
|
|
119
|
+
if canonical == SELF_ORGANIZATION:
|
|
120
|
+
open_thol = True
|
|
121
|
+
elif open_thol and canonical in SELF_ORGANIZATION_CLOSURES:
|
|
122
|
+
open_thol = False
|
|
123
|
+
|
|
124
|
+
ok, msg = _validate_known_tokens(token_to_canonical)
|
|
125
|
+
if not ok:
|
|
126
|
+
return False, msg
|
|
127
|
+
ok, msg = _validate_intermediate(found_reception, found_coherence, seen_intermediate)
|
|
128
|
+
if not ok:
|
|
129
|
+
return False, msg
|
|
130
|
+
ok, msg = _validate_end(names[-1], open_thol)
|
|
131
|
+
if not ok:
|
|
132
|
+
return False, msg
|
|
133
|
+
return True, "ok"
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def validate_sequence(
|
|
137
|
+
names: Iterable[str] | object = _MISSING, **kwargs: object
|
|
138
|
+
) -> tuple[bool, str]:
|
|
139
|
+
"""Validate minimal TNFR syntax rules."""
|
|
140
|
+
|
|
141
|
+
if kwargs:
|
|
142
|
+
unexpected = ", ".join(sorted(kwargs))
|
|
143
|
+
raise TypeError(
|
|
144
|
+
f"validate_sequence() got unexpected keyword argument(s): {unexpected}"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
if names is _MISSING:
|
|
148
|
+
raise TypeError("validate_sequence() missing required argument: 'names'")
|
|
149
|
+
|
|
150
|
+
sequence = list(names)
|
|
151
|
+
return _validate_token_sequence(sequence)
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tnfr
|
|
3
|
+
Version: 6.0.0
|
|
4
|
+
Summary: Modular structural-based dynamics on networks.
|
|
5
|
+
Author: fmg
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://pypi.org/project/tnfr/
|
|
8
|
+
Project-URL: Repository, https://github.com/fermga/TNFR-Python-Engine
|
|
9
|
+
Project-URL: GPT, https://chatgpt.com/g/g-67abc78885a88191b2d67f94fd60dc97-tnfr-teoria-de-la-naturaleza-fractal-resonante
|
|
10
|
+
Keywords: TNFR,complex systems,fractals,resonance,networks,structural dynamics,structural analysis
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Intended Audience :: Science/Research
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE.md
|
|
26
|
+
Requires-Dist: networkx>=2.6
|
|
27
|
+
Requires-Dist: cachetools>=5
|
|
28
|
+
Requires-Dist: typing-extensions>=4.4; python_version < "3.10"
|
|
29
|
+
Provides-Extra: numpy
|
|
30
|
+
Requires-Dist: numpy>=1.24; extra == "numpy"
|
|
31
|
+
Provides-Extra: yaml
|
|
32
|
+
Requires-Dist: pyyaml>=6.0; extra == "yaml"
|
|
33
|
+
Provides-Extra: orjson
|
|
34
|
+
Requires-Dist: orjson>=3; extra == "orjson"
|
|
35
|
+
Provides-Extra: test
|
|
36
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
37
|
+
Requires-Dist: pytest-benchmark>=4; extra == "test"
|
|
38
|
+
Requires-Dist: pydocstyle>=6; extra == "test"
|
|
39
|
+
Requires-Dist: coverage>=7; extra == "test"
|
|
40
|
+
Requires-Dist: flake8>=5; extra == "test"
|
|
41
|
+
Requires-Dist: flake8-pyproject>=1.2; extra == "test"
|
|
42
|
+
Requires-Dist: vulture>=2; extra == "test"
|
|
43
|
+
Provides-Extra: typecheck
|
|
44
|
+
Requires-Dist: mypy>=1.8; extra == "typecheck"
|
|
45
|
+
Requires-Dist: networkx-stubs>=0.0.1; extra == "typecheck"
|
|
46
|
+
Requires-Dist: types-cachetools>=6.0.0.0; extra == "typecheck"
|
|
47
|
+
Requires-Dist: numpy>=1.24; extra == "typecheck"
|
|
48
|
+
Dynamic: license-file
|
|
49
|
+
|
|
50
|
+
# TNFR Python Engine
|
|
51
|
+
|
|
52
|
+
Canonical implementation of the Resonant Fractal Nature Theory (TNFR) for modelling structural
|
|
53
|
+
coherence. The engine seeds resonant nodes, applies structural operators, coordinates
|
|
54
|
+
ΔNFR/phase dynamics, and measures coherence metrics (C(t), Si, νf) without breaking the nodal
|
|
55
|
+
equation $\partial EPI/\partial t = \nu_f \cdot \Delta NFR(t)$.
|
|
56
|
+
|
|
57
|
+
## Snapshot
|
|
58
|
+
|
|
59
|
+
- **Operate:** build nodes with `tnfr.create_nfr`, execute trajectories via
|
|
60
|
+
`tnfr.structural.run_sequence`, and evolve dynamics with `tnfr.dynamics.run`.
|
|
61
|
+
- **Observe:** register metrics/trace callbacks to capture ΔNFR, C(t), Si, and structural
|
|
62
|
+
histories
|
|
63
|
+
for every run.
|
|
64
|
+
- **Extend:** rely on the canonical operator grammar and invariants before introducing new
|
|
65
|
+
utilities or telemetry.
|
|
66
|
+
|
|
67
|
+
## Quickstart
|
|
68
|
+
|
|
69
|
+
Install from PyPI (Python ≥ 3.9):
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install tnfr
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Then follow the [quickstart guide](docs/getting-started/quickstart.md) for Python and CLI
|
|
76
|
+
walkthroughs plus optional dependency caching helpers.
|
|
77
|
+
|
|
78
|
+
## Documentation map
|
|
79
|
+
|
|
80
|
+
- [Documentation index](docs/index.md) — navigation hub for API chapters and examples.
|
|
81
|
+
- [API overview](docs/api/overview.md) — package map, invariants, and structural data flow.
|
|
82
|
+
- [Structural operators](docs/api/operators.md) — canonical grammar, key concepts, and typical
|
|
83
|
+
workflows.
|
|
84
|
+
- [Telemetry & utilities](docs/api/telemetry.md) — coherence metrics, trace capture, locking,
|
|
85
|
+
and helper facades.
|
|
86
|
+
- [Examples](docs/examples/README.md) — runnable scenarios, CLI artefacts, and token legend.
|
|
87
|
+
|
|
88
|
+
## Documentation build workflow
|
|
89
|
+
|
|
90
|
+
Netlify publishes the documentation with [MkDocs](https://www.mkdocs.org/) so the generated
|
|
91
|
+
site preserves the canonical TNFR structure. The same steps can be executed locally:
|
|
92
|
+
|
|
93
|
+
1. Create and activate a virtual environment (e.g. `python -m venv .venv && source .venv/bin/activate`).
|
|
94
|
+
2. Install the documentation toolchain: `python -m pip install -r docs/requirements.txt`.
|
|
95
|
+
3. Preview changes live with `mkdocs serve` or reproduce the Netlify pipeline with
|
|
96
|
+
`mkdocs build`, which writes the static site to the `site/` directory.
|
|
97
|
+
|
|
98
|
+
The Netlify build (`netlify.toml`) runs `python -m pip install -r docs/requirements.txt && mkdocs build`
|
|
99
|
+
and publishes the resulting `site/` directory, ensuring the hosted documentation matches local builds.
|
|
100
|
+
|
|
101
|
+
## Local development
|
|
102
|
+
|
|
103
|
+
Use the helper scripts to keep formatting aligned with the canonical configuration and to reproduce
|
|
104
|
+
the quality gate locally:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
./scripts/format.sh # Apply Black and isort across src/, tests/, scripts/, and benchmarks/
|
|
108
|
+
./scripts/format.sh --check # Validate formatting without modifying files
|
|
109
|
+
./scripts/run_tests.sh # Execute the full QA battery (type checks, tests, coverage, linting)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The formatting helper automatically prefers `poetry run` when a Poetry environment is available and
|
|
113
|
+
falls back to `python -m` invocations so local runs mirror the tooling invoked in continuous
|
|
114
|
+
integration.
|
|
115
|
+
|
|
116
|
+
## Additional resources
|
|
117
|
+
|
|
118
|
+
- [ARCHITECTURE.md](ARCHITECTURE.md) — orchestration layers and invariant enforcement.
|
|
119
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md) — QA battery (`scripts/run_tests.sh`) and review
|
|
120
|
+
expectations.
|
|
121
|
+
- [TNFR.pdf](TNFR.pdf) — theoretical background, structural operators, and paradigm glossary.
|
|
122
|
+
|
|
123
|
+
## Migration notes
|
|
124
|
+
|
|
125
|
+
- **Si dispersion keys:** Replace any remaining ``dSi_ddisp_fase`` entries in graph payloads
|
|
126
|
+
or configuration files with the English ``dSi_dphase_disp`` key before upgrading. The
|
|
127
|
+
runtime now raises :class:`ValueError` listing any unexpected sensitivity keys, and
|
|
128
|
+
:func:`tnfr.metrics.sense_index.compute_Si_node` rejects unknown keyword arguments.
|
|
129
|
+
- Refer to the [release notes](docs/releases.md#1100-si-dispersion-legacy-keys-removed) for
|
|
130
|
+
a migration snippet that rewrites stored graphs in place prior to running the new version.
|
|
131
|
+
|
|
132
|
+
## Licensing
|
|
133
|
+
|
|
134
|
+
Released under the [MIT License](LICENSE.md). Cite the TNFR paradigm when publishing research
|
|
135
|
+
or derived artefacts based on this engine.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
tnfr/__init__.py,sha256=zgPWxn__aqj45uTXna_lzywQ-5-TuxBYYt-BkMLXPiY,8679
|
|
2
|
+
tnfr/__init__.pyi,sha256=SVeCTtSpwlP-gtTzhX8OINlfFFuO43pyWunsc2I021Y,978
|
|
3
|
+
tnfr/_compat.py,sha256=VuXrIrkfwCGk_KJjgubhh3JE3S49Q6zoNaKgMVgpXFE,414
|
|
4
|
+
tnfr/_version.py,sha256=QBM2cy3Ta0_p9NQaMtYXdirM5XzS5wVntliMx9BDMgM,125
|
|
5
|
+
tnfr/_version.pyi,sha256=DbyhsjJTujojo0nxFtOdH94bxGxzReRJNjZoHV-zG1s,95
|
|
6
|
+
tnfr/alias.py,sha256=WfddprBly1jwWz10ozYErCi5I2ONAXjf2dwpOBxyqF8,18127
|
|
7
|
+
tnfr/alias.pyi,sha256=x4sS9Rt_M-pzQF_tJitR-HRxoyKNrn1s1lIj8zcV9us,2926
|
|
8
|
+
tnfr/cache.py,sha256=D5EZ1yDBQoXYcGH89wsdlnaojU3eH-MUACX8VDXWhFI,24442
|
|
9
|
+
tnfr/cache.pyi,sha256=MIH_3rs5OE1xt2VYOziShL0hGRctHFx2i7PThT-X3qw,5872
|
|
10
|
+
tnfr/callback_utils.py,sha256=YjGq7viVC95wFpSBJIt2fFDCp7OUWwpv5FpiWsTuzYA,12181
|
|
11
|
+
tnfr/callback_utils.pyi,sha256=Osu0xb9opdU7KeWC4MleelthiJHVqhZ4ia8UrRxOtvs,2365
|
|
12
|
+
tnfr/constants_glyphs.py,sha256=o0uTYkuLXaj3yM4CGAcnNcqwv9VC0I6x-hJzCPbzq9Q,401
|
|
13
|
+
tnfr/constants_glyphs.pyi,sha256=Xtm8NhTukF_rpn4Y7hy9O7aT1IcWSuQLcDpFcUnZnbk,192
|
|
14
|
+
tnfr/execution.py,sha256=md_Mzpe6M7VsQBt8_brKQPFfhnoRWftxi7YZC-LzmYM,5813
|
|
15
|
+
tnfr/execution.pyi,sha256=iPskC4i_jBPwNtvCXVr5tH71WD9mQCqAvKq7QjKDi2w,1465
|
|
16
|
+
tnfr/flatten.py,sha256=QbrZODPL0qTu9D7RVn3YGvq8QEq6f0GR60X-1kLho3c,8226
|
|
17
|
+
tnfr/flatten.pyi,sha256=dI7sVL2BTvFYvN6bWoQVtIKybOXZSogeko3pCvtp9Vo,594
|
|
18
|
+
tnfr/gamma.py,sha256=nkbBcP3H0gBZV_vABphsaY-Ick1i4gDj_X9PFnRoSQM,10998
|
|
19
|
+
tnfr/gamma.pyi,sha256=b2KKWTBGQ4fAMYIBUTumIFgS73xixk9ekd01cGNyFV4,1005
|
|
20
|
+
tnfr/glyph_history.py,sha256=ajLN0PIZWEQkaIaF8pJonseqAsem0utDZCD-UXirrWo,11527
|
|
21
|
+
tnfr/glyph_history.pyi,sha256=rRAu_jVFfkE7o7l1VE9-CSWXCnbfRs2BG_4WjYPQF_s,1397
|
|
22
|
+
tnfr/grammar.py,sha256=70lUuMqoB3GVomKD4rbQy_M5icBjp0-4XKwyAT6Z_gE,651
|
|
23
|
+
tnfr/grammar.pyi,sha256=UM6ntYDCQ3hEfYnV6e2O9K9G21VTkpx-YJYnX5j-2Lw,236
|
|
24
|
+
tnfr/immutable.py,sha256=SeNqRmbomKJjU6wC_ITe9gBGn9xEZjV1z67UQioSg7g,6445
|
|
25
|
+
tnfr/immutable.pyi,sha256=DHx-gRaygFPX2G5zfDQUjLsRB-tW5sZhhBRc16woD9I,1283
|
|
26
|
+
tnfr/initialization.py,sha256=ds8NfUEBku6pzIwWHNPOO8y1Gubio5dK6fYS80IHUJo,5914
|
|
27
|
+
tnfr/initialization.pyi,sha256=hDr2PMQmpye4xoA7m5Fgbpr-p2FLg3_LVSXu6D-apj0,1345
|
|
28
|
+
tnfr/io.py,sha256=U6eMQNSGa2wkHC7tsUrAq19UuPntoWiuCwd-br14qws,8316
|
|
29
|
+
tnfr/io.pyi,sha256=_x06jeSFJVJsyksACDnq9S-4l5X01YXlxn44y9ACXCA,181
|
|
30
|
+
tnfr/locking.py,sha256=mOvaENBNSsWw6KiBG_UXv4xXfZ9uQZvWw5SN2cKFmSU,1168
|
|
31
|
+
tnfr/locking.pyi,sha256=GoQ-C3l87O78jCi38VmUDpXwMnocPe0eavJFEN4QdXU,92
|
|
32
|
+
tnfr/node.py,sha256=qyEJ3ogOZoO9lAlCW3uyDhpRKqF7BinKrRy35ZywHGQ,7869
|
|
33
|
+
tnfr/node.pyi,sha256=uLAM1iu10BW3s8O7BwJcc1PWYE0v9YIQxVT1ZxYG2SE,3450
|
|
34
|
+
tnfr/observers.py,sha256=34OWK8YcE2m4UyqJeQMxpQBOv_KjSO4JG80F3nVziVI,5118
|
|
35
|
+
tnfr/observers.pyi,sha256=_mLFNOwrJAZb894noHW9Y94xBd4Dap3LHV8vx-L8oNk,881
|
|
36
|
+
tnfr/ontosim.py,sha256=Oqrgjib5J6igPi2sVbFJMLHKgw005lCVHPoZuboo08o,4035
|
|
37
|
+
tnfr/ontosim.pyi,sha256=__X4twVj8Y7uirGqx5UDlzMIYOBoU8ZqRBKOf836e6Q,565
|
|
38
|
+
tnfr/presets.py,sha256=FL2Fvi2mazD4PvaOxIosrQOnZ7KvNia-fiCf-4sF80U,312
|
|
39
|
+
tnfr/presets.pyi,sha256=8oHCzjv8AOcfWWRZb4pgTJ40HJUXbbrDOyQoSb_XsD8,94
|
|
40
|
+
tnfr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
|
+
tnfr/rng.py,sha256=BzrmsBXHdKsS1pt4u4J6VFA8AaH8Qh4yOjN_vjGMsYU,14122
|
|
42
|
+
tnfr/rng.pyi,sha256=95PakrXx9OYVrEUIrwR9xxuuGxiYK1ZZXWNm0cLf1AA,232
|
|
43
|
+
tnfr/selector.py,sha256=CuiMRNJ_isi_mRVfhWeyhrY1DfdOhn8VSXddArn1zhg,6164
|
|
44
|
+
tnfr/selector.pyi,sha256=LWwkUQloGu7SZFi4aedJA7snFd16oA9yaPYQP2tzvTY,379
|
|
45
|
+
tnfr/sense.py,sha256=ZUiaFJsP8wz5AkCywLxJN3dz1V9huFfnlE6m5InyvWQ,10148
|
|
46
|
+
tnfr/sense.pyi,sha256=9u-nqIEPaFp2GSrJF9AyNJEbhPnw-IjoIDM8QMc_R5I,794
|
|
47
|
+
tnfr/structural.py,sha256=_o8Kqaue3o7ohyozwbCO0taTEn4nLVNfE7P4F37KJDw,2526
|
|
48
|
+
tnfr/structural.pyi,sha256=WYLGl2quXH3iSnDZu0-ZKwsdGZLDpBtaWo0K3GOMQeY,847
|
|
49
|
+
tnfr/tokens.py,sha256=IOLowDN6JuiEVAnGcYtclpF_S9Orlu5BnEug5O3aERA,1214
|
|
50
|
+
tnfr/tokens.pyi,sha256=qo_cfFE3vybigYl6Bx6pstRwn0ay2Sdf91S5o8YWce0,683
|
|
51
|
+
tnfr/trace.py,sha256=y8bDQ4Rpb5DEr5qfnmZLcNty3pDKBhujYO7U8F5jrc8,15043
|
|
52
|
+
tnfr/trace.pyi,sha256=anufYVC1K-5UyoGcEk12f1BtGAwPG1bOUfT6XjQZxHk,1882
|
|
53
|
+
tnfr/types.py,sha256=t6jd_Wb3V1OuWUAx3ycmCbFje2Sshj6B8TOJNrv7MtI,11351
|
|
54
|
+
tnfr/types.pyi,sha256=VyfkdeGuwJP_3RXbVV4SozINJm7jr3XMEU9clJw6Mrw,4022
|
|
55
|
+
tnfr/cli/__init__.py,sha256=FTblTvNLe0v2QIrsMgiWwcD0_JoRkNOVsIwGlyk_4sE,2127
|
|
56
|
+
tnfr/cli/__init__.pyi,sha256=XYq749MAzQHqV9Lj7QHjN6I2qMTZTEP07w8S-odcNS0,1040
|
|
57
|
+
tnfr/cli/arguments.py,sha256=pklvrCn2AjD5gmCjfJpNs9UQLFGA2NziBh7HjVbkL80,6336
|
|
58
|
+
tnfr/cli/arguments.pyi,sha256=KzXFsqSohTnvvTAkMWBgRykWv2Fuc-lfIjbKyibY84s,1031
|
|
59
|
+
tnfr/cli/execution.py,sha256=jP8NMwKBDQZ-KvC0pVZStEnIUaSh-K_meIBiQSbW0Nk,9897
|
|
60
|
+
tnfr/cli/execution.pyi,sha256=IStpTub_NLFdMxMej3v15s7NPfIJB8hkL0pW_YuVdJc,2212
|
|
61
|
+
tnfr/cli/utils.py,sha256=aTsWm1b5QRZp4ZZStA1kqHiYT_wboqEpyTVNXVXnOoQ,977
|
|
62
|
+
tnfr/cli/utils.pyi,sha256=3ODz7i3t2cm9qjXfxzdLQgnfZHBdXTewEVsbwZdQGgs,105
|
|
63
|
+
tnfr/config/__init__.py,sha256=hcAneY0S8dH9kjHDBH7rlGbPH6r0F_WpkZ8J-5c4Q0M,384
|
|
64
|
+
tnfr/config/__init__.pyi,sha256=m1D1GQIyCbwnllwXNoPriPkxzBYIJUZBik-jJXdW_CA,113
|
|
65
|
+
tnfr/config/constants.py,sha256=8d_nXHpuM7DBKMeKonT0Wwft-oZgKxljYdhhZOOzceg,2830
|
|
66
|
+
tnfr/config/constants.pyi,sha256=Xtm8NhTukF_rpn4Y7hy9O7aT1IcWSuQLcDpFcUnZnbk,192
|
|
67
|
+
tnfr/config/init.py,sha256=srfCPDT8ddj2N2B7i9raHQeYKv3m2yswCKM67o7cfFQ,1029
|
|
68
|
+
tnfr/config/init.pyi,sha256=m1D1GQIyCbwnllwXNoPriPkxzBYIJUZBik-jJXdW_CA,113
|
|
69
|
+
tnfr/config/operator_names.py,sha256=iSefOgf-qniQI5OQhgH7auhVRveoX_0n3mkP11xHOdo,2705
|
|
70
|
+
tnfr/config/operator_names.pyi,sha256=9GgUMxZXzoemlnIjkTmtruOJ2DkA__DfjQTeouRNVu4,532
|
|
71
|
+
tnfr/config/presets.py,sha256=XHGkFAjBQ6t34xgMeL_9O-S2jPaXhEfgysEFhXcMlmQ,2481
|
|
72
|
+
tnfr/config/presets.pyi,sha256=8oHCzjv8AOcfWWRZb4pgTJ40HJUXbbrDOyQoSb_XsD8,94
|
|
73
|
+
tnfr/constants/__init__.py,sha256=2aMheGK04vELJARf47xHxkNZThQcSJPSoOV8kb3VqtE,6479
|
|
74
|
+
tnfr/constants/__init__.pyi,sha256=ukJKlu9VkWHKlcKlv_pyXHBKjE6HMqYckAO4pF6LqGc,2270
|
|
75
|
+
tnfr/constants/core.py,sha256=F7kVXaP_-nVhZIDq4327Z2Kxp2AI8yab8WGHDePIgTw,4718
|
|
76
|
+
tnfr/constants/core.pyi,sha256=H9oY3Skdse9qPSFw2gF7mpyAUzFCPwo3RaYIVnxDfvo,279
|
|
77
|
+
tnfr/constants/init.py,sha256=WdMKkdPKO7vyQoJAuoFnhWbb3n1nBkmkzprwyYj_ZN8,805
|
|
78
|
+
tnfr/constants/init.pyi,sha256=jdf_jVgcRlVxzFzioOw_ANXUbtAc-0iHfLLAT1tLyaw,169
|
|
79
|
+
tnfr/constants/metric.py,sha256=P7Zrw-4p7Nd7QwCVLRMV7GWop3LoeAdlm9NgAQnnbJU,3290
|
|
80
|
+
tnfr/constants/metric.pyi,sha256=x0U5uD9fzgmSUz_EoUdBE2zrEdbgnaMgbMxUFyA7vB8,280
|
|
81
|
+
tnfr/dynamics/__init__.py,sha256=OBfdBpz52CTv_nlhFc8arfnACwwoRr9O1iJpGITzi2E,3296
|
|
82
|
+
tnfr/dynamics/__init__.pyi,sha256=cRvvBpMV7G_5YF_mDJkvEcN1wTGBmdeEs-PJIihiZ1Q,1843
|
|
83
|
+
tnfr/dynamics/adaptation.py,sha256=WkmuLYY5wTvOJbeGKLfYAk2jYdP5caPVBPpib9fqTq8,7072
|
|
84
|
+
tnfr/dynamics/aliases.py,sha256=8SeUcsJRieXrvl7-oJiEcvLUke1AQSZnz4-djVJdeHg,445
|
|
85
|
+
tnfr/dynamics/coordination.py,sha256=VKlgqS7DA-2tWklwJUlD8DICJdiFGZX1gYMIElMeC_w,10814
|
|
86
|
+
tnfr/dynamics/dnfr.py,sha256=YXEpE-b5EWc1EFSBCneAf_GwK3JCUALw2JM3pGwmnzk,75723
|
|
87
|
+
tnfr/dynamics/dnfr.pyi,sha256=-hiGDoEEFtLb9Ggox1jhE_-ehkiaBL1kh7ClV-8913M,655
|
|
88
|
+
tnfr/dynamics/integrators.py,sha256=9zYrV4kr_s8L5CKPoXKwath0UIw_3r52jqce3jy95ks,16495
|
|
89
|
+
tnfr/dynamics/integrators.pyi,sha256=6bJaNKzZ5b1s5u4gktB1eACRH4oxVQNJTil-f1O02vI,843
|
|
90
|
+
tnfr/dynamics/runtime.py,sha256=ymP5BXZq5S7GtvfePUObMuMHMIhbUy6d6ZQbjcTYFU4,14762
|
|
91
|
+
tnfr/dynamics/sampling.py,sha256=FR2VAgcHc0eiUAK7YdAn6Ad1Vq2VtZTMceyOQzlqEno,1247
|
|
92
|
+
tnfr/dynamics/sampling.pyi,sha256=edfyDqgtvmK4w6zlBNG9nmGpZDVe3pdnNZYOLFbwIG8,102
|
|
93
|
+
tnfr/dynamics/selectors.py,sha256=a8M26H3K5ywJm4u5vTNt4yzrjR2FG5m-e6BMRE0v4YU,22447
|
|
94
|
+
tnfr/helpers/__init__.py,sha256=DrT3dtkR6oJ2-uv3XE_fbd7Pq69_tbyninrGMAtEAVQ,4042
|
|
95
|
+
tnfr/helpers/__init__.pyi,sha256=dae6lQfR-iXR1FJF9kSUKgqlzlH6dju7803AqsSbRco,1688
|
|
96
|
+
tnfr/helpers/numeric.py,sha256=ritFewhW1VNxCOHxBC71aNLSZUuJ23-MUsVn_IV7V8E,2693
|
|
97
|
+
tnfr/helpers/numeric.pyi,sha256=m6Tf_k9ZH2sro6z6g0wxariWSip6rVMct288zMDDcvo,174
|
|
98
|
+
tnfr/metrics/__init__.py,sha256=4gujlyn3aN95lkxCjQPPgKS_xJYm5ShcraeEkDYKR_E,885
|
|
99
|
+
tnfr/metrics/__init__.pyi,sha256=W5fUkKR9FeEcdHg4OVW2JPzxIRlQ71qtiYqoaEoAM3w,412
|
|
100
|
+
tnfr/metrics/coherence.py,sha256=BVzoJSLCt--eDaFTmTEYfRObZkRXjQgn_KzAcYcXQK0,46109
|
|
101
|
+
tnfr/metrics/common.py,sha256=R7jOzuxpenNkv-Y0iURMQOA9vtLTxr5Hdmna1OXohKA,4361
|
|
102
|
+
tnfr/metrics/common.pyi,sha256=QSOfl14yyDpQ0B6VvI3ecvpAH99mkrFXU35rJg_lXjU,289
|
|
103
|
+
tnfr/metrics/core.py,sha256=1L1shli3RxlGn4Y8xuYrsNfaE-9I3Qx7kHMXLwdfq7A,7208
|
|
104
|
+
tnfr/metrics/core.pyi,sha256=8s1j3oeTyzU5xyUIsuP_Q5DkXY6hja_j2xL7ghKcu-U,218
|
|
105
|
+
tnfr/metrics/diagnosis.py,sha256=P42FWqhOs955UB1cPm0rf1lFVB7wyz_0HLLoUFSeYII,26509
|
|
106
|
+
tnfr/metrics/diagnosis.pyi,sha256=I2PzErqAVEvYt8saFs8fF7ADFUXEwzPwiKuzRmR8XGs,2134
|
|
107
|
+
tnfr/metrics/export.py,sha256=F-gEES5RZopTRE45ISzYPRF_4ZF5HDa3qF_XNvurVE0,4735
|
|
108
|
+
tnfr/metrics/glyph_timing.py,sha256=0gdxDu-aMd6mlau_VCWpZxCxSZ6Iau53sCFDFpF7Wug,10851
|
|
109
|
+
tnfr/metrics/reporting.py,sha256=XcBwZl1-kwYLqxZELLR9oPsTVN--Z_thWqzVIANlVC4,4121
|
|
110
|
+
tnfr/metrics/reporting.pyi,sha256=uA7DP9bM7351dcq4qBooZDXJUSLXyWR3AE2_r9H29YI,194
|
|
111
|
+
tnfr/metrics/sense_index.py,sha256=qAUt1zbmSvvFGRusmQ5ssUaScuLCdNLnVO6BCS4hPNQ,9314
|
|
112
|
+
tnfr/metrics/sense_index.pyi,sha256=YK5rIvhGGN6KyZHVIirCrgBF3eDeJ2zPyfa7x19sqXM,135
|
|
113
|
+
tnfr/metrics/trig.py,sha256=Jyg9uwqNjSVRYFnYtyjrqnWSsFPKnrB6qcLof_tTD4Y,6548
|
|
114
|
+
tnfr/metrics/trig.pyi,sha256=nSssWGsGS7k4jvKWAYxICzoB13laM8PKTpPstWgIJNQ,249
|
|
115
|
+
tnfr/metrics/trig_cache.py,sha256=IPPIopGf5za8filSUGeymNHXEwfMZSRp0SNYgMdkHkc,3009
|
|
116
|
+
tnfr/metrics/trig_cache.pyi,sha256=wqxVFp27iiUBB9Uep8rEIU_MIh1PjtsaK_d2RpLGnfE,163
|
|
117
|
+
tnfr/operators/__init__.py,sha256=ea7doh9GgKIHpFOxkI4-ladMQcnIkWD1rvjurxx_ffA,13394
|
|
118
|
+
tnfr/operators/__init__.pyi,sha256=5xE25x2yK-o0JuqxbUmlP62dRXW4uWFDYcHfR5SifKg,588
|
|
119
|
+
tnfr/operators/definitions.py,sha256=4KG8BtIQ2sXKzyylqSoeJFnECdKVCujoVfFLHU4-iTY,3985
|
|
120
|
+
tnfr/operators/definitions.pyi,sha256=9Zj4-HjCy8kX3havevz5EPL5q3TtMuyabxfHRw95bak,1528
|
|
121
|
+
tnfr/operators/jitter.py,sha256=nO7gY2466UcKOYlpaVDEi4d5wvvNJRJWsbLU5xmcp0E,7833
|
|
122
|
+
tnfr/operators/jitter.pyi,sha256=FSrSKP51D5N7AdekOH9H-sVzBBaqnnmM2IQKfWlnQN0,188
|
|
123
|
+
tnfr/operators/registry.py,sha256=b7dO6n3gpUXgnYPhJhAQd0oElYNol43jkeQCP8iZn3U,2433
|
|
124
|
+
tnfr/operators/registry.pyi,sha256=CHuuHsvKsSo7mWSXMQJdJoXD0AHO6jrCjv8lVGuoEkY,314
|
|
125
|
+
tnfr/operators/remesh.py,sha256=VKqIucYJkQWUc1Ux0RlEpa8wOSjtN3u8MZWMt-0WdxQ,17869
|
|
126
|
+
tnfr/telemetry/__init__.py,sha256=Ugqk4Qiv4dIYTVpxGXdKnEBORDdmw19A7Ni2TBPsp7o,286
|
|
127
|
+
tnfr/telemetry/verbosity.py,sha256=6fN7IMhwtLKVQbch-PIN_vLxn3dw178SownD8-xlhKM,1048
|
|
128
|
+
tnfr/utils/__init__.py,sha256=UOUnzZVN-WGqyCHVGYiM9xkwwb83Mm4N6AqXySV_Da0,4375
|
|
129
|
+
tnfr/utils/__init__.pyi,sha256=EC12WoblgdRd4q_49XinqXklju2hyN9lvGUXbKRtCcw,2946
|
|
130
|
+
tnfr/utils/cache.py,sha256=brzDTG_cFBy8ENZs2je3GbFRgGKGl2t8bI8QsiIGd4c,22602
|
|
131
|
+
tnfr/utils/cache.pyi,sha256=sZnm7KKTvpM9CwI2y5v2G9L1NW3Gbo4MNMtC-_zZhOE,3782
|
|
132
|
+
tnfr/utils/data.py,sha256=nQFN0aWYHTX36UkniGXzBrqNYxCabBLVL2Rh99-y8ts,7805
|
|
133
|
+
tnfr/utils/data.pyi,sha256=O3Iy37c8KUE6kFozWTAU2FyaWuUGIrIM3sxdaBgpap4,1595
|
|
134
|
+
tnfr/utils/graph.py,sha256=wnkkAB-yS2KlGRWcwfLwdHjJLcenaa8S2xEzzsVHcRE,2780
|
|
135
|
+
tnfr/utils/graph.pyi,sha256=mrMVWDkJQhu8K3l2eUvOSgKCWlWij7e8pANzJjOFXKA,165
|
|
136
|
+
tnfr/utils/init.py,sha256=4tP7frGVtapI_TLWFW8k83AIzXL3FaGGjDPSmSrcJsU,22561
|
|
137
|
+
tnfr/utils/init.pyi,sha256=26t_q-CeJ5BDyXu80QsYojBknKlKQl7AoRTVgrbQNVw,2446
|
|
138
|
+
tnfr/utils/io.py,sha256=W3-aZ3axvLx0gmYR2zUmUvs9yMH2UPRIbp9Y-Z__rws,4730
|
|
139
|
+
tnfr/utils/io.pyi,sha256=l2_9a0mYrsnM4Frpi7jCxeueUD3-e6fYyKpZVya6ARY,168
|
|
140
|
+
tnfr/utils/validators.py,sha256=R0bvCZO0qXP1OqiVEKLMBX4P5nsy-tyuWKVf6mteg3E,3892
|
|
141
|
+
tnfr/utils/validators.pyi,sha256=6nPYp8N_vLAA8FNyQM_5iR41W8-OZS9oEdZwAz219uw,513
|
|
142
|
+
tnfr/validation/__init__.py,sha256=tVsCpQKc4SoBoQdKktI2pFDsaxzoeZXExSiW-ulXh5o,617
|
|
143
|
+
tnfr/validation/__init__.pyi,sha256=nSObG9II_9WCpYvvw3bOjIjw0iXHw8Sr0bazmXwR94k,315
|
|
144
|
+
tnfr/validation/compatibility.py,sha256=FNNU8VotjVv7eRFMDolixZC7vlsSZRqWLriqkH_gjLk,1788
|
|
145
|
+
tnfr/validation/compatibility.pyi,sha256=ELqyFWaYRgJzcuO-930v0eKxYxJFNCn2-P_AlOvSA-s,116
|
|
146
|
+
tnfr/validation/grammar.py,sha256=XmdRjtkvVWsC4qclG66vR37srO2vtohQgSGDTXIRpz8,4387
|
|
147
|
+
tnfr/validation/grammar.pyi,sha256=uavU-at-x10RBpFw_YcUC7yLepx1uo1B1sJYPGRWH0E,198
|
|
148
|
+
tnfr/validation/rules.py,sha256=fVJ5gX4bUkJQJsA4gBc0IMzirSUUHiGs_fj3sS5yIbM,5814
|
|
149
|
+
tnfr/validation/rules.pyi,sha256=WuHUQDS2o4Wrj7BRovHvwbQ6DiQSomJVgYWB0eyDL5M,305
|
|
150
|
+
tnfr/validation/syntax.py,sha256=O2cpQHv2FABfH7CCIcvg_Kw8zyHMzrwSF5VwjBNCrLg,4573
|
|
151
|
+
tnfr/validation/syntax.pyi,sha256=c8seASIj0bdS0Wof6AhupuTqkvC1x9FdmeEFk8SbETg,101
|
|
152
|
+
tnfr-6.0.0.dist-info/licenses/LICENSE.md,sha256=SRvvhXLrKtseuK6DARbuJffuXOXqAyk3wvF2n0t1SWA,1109
|
|
153
|
+
tnfr-6.0.0.dist-info/METADATA,sha256=61t5DnOqYNsIzIMnNDK8t50Bm3iKIfOwKqhN-_dSeP0,6226
|
|
154
|
+
tnfr-6.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
155
|
+
tnfr-6.0.0.dist-info/entry_points.txt,sha256=j4-QRHqeT2WnchHe_mvK7npGTLjlyfLpvRONFe9Z4MU,39
|
|
156
|
+
tnfr-6.0.0.dist-info/top_level.txt,sha256=Q2HJnvc5Rt2VHwVvyBTnNPT4SfmJWnCj7XUxxEvQa7c,5
|
|
157
|
+
tnfr-6.0.0.dist-info/RECORD,,
|