tnfr 4.5.2__py3-none-any.whl → 8.5.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.
- tnfr/__init__.py +334 -50
- tnfr/__init__.pyi +33 -0
- tnfr/_compat.py +10 -0
- tnfr/_generated_version.py +34 -0
- tnfr/_version.py +49 -0
- tnfr/_version.pyi +7 -0
- tnfr/alias.py +214 -37
- tnfr/alias.pyi +108 -0
- tnfr/backends/__init__.py +354 -0
- tnfr/backends/jax_backend.py +173 -0
- tnfr/backends/numpy_backend.py +238 -0
- tnfr/backends/optimized_numpy.py +420 -0
- tnfr/backends/torch_backend.py +408 -0
- tnfr/cache.py +149 -556
- tnfr/cache.pyi +13 -0
- tnfr/cli/__init__.py +51 -16
- tnfr/cli/__init__.pyi +26 -0
- tnfr/cli/arguments.py +344 -32
- tnfr/cli/arguments.pyi +29 -0
- tnfr/cli/execution.py +676 -50
- tnfr/cli/execution.pyi +70 -0
- tnfr/cli/interactive_validator.py +614 -0
- tnfr/cli/utils.py +18 -3
- tnfr/cli/utils.pyi +7 -0
- tnfr/cli/validate.py +236 -0
- tnfr/compat/__init__.py +85 -0
- tnfr/compat/dataclass.py +136 -0
- tnfr/compat/jsonschema_stub.py +61 -0
- tnfr/compat/matplotlib_stub.py +73 -0
- tnfr/compat/numpy_stub.py +155 -0
- tnfr/config/__init__.py +224 -0
- tnfr/config/__init__.pyi +10 -0
- tnfr/{constants_glyphs.py → config/constants.py} +26 -20
- tnfr/config/constants.pyi +12 -0
- tnfr/config/defaults.py +54 -0
- tnfr/{constants/core.py → config/defaults_core.py} +59 -6
- tnfr/config/defaults_init.py +33 -0
- tnfr/config/defaults_metric.py +104 -0
- tnfr/config/feature_flags.py +81 -0
- tnfr/config/feature_flags.pyi +16 -0
- tnfr/config/glyph_constants.py +31 -0
- tnfr/config/init.py +77 -0
- tnfr/config/init.pyi +8 -0
- tnfr/config/operator_names.py +254 -0
- tnfr/config/operator_names.pyi +36 -0
- tnfr/config/physics_derivation.py +354 -0
- tnfr/config/presets.py +83 -0
- tnfr/config/presets.pyi +7 -0
- tnfr/config/security.py +927 -0
- tnfr/config/thresholds.py +114 -0
- tnfr/config/tnfr_config.py +498 -0
- tnfr/constants/__init__.py +51 -133
- tnfr/constants/__init__.pyi +92 -0
- tnfr/constants/aliases.py +33 -0
- tnfr/constants/aliases.pyi +27 -0
- tnfr/constants/init.py +3 -1
- tnfr/constants/init.pyi +12 -0
- tnfr/constants/metric.py +9 -15
- tnfr/constants/metric.pyi +19 -0
- tnfr/core/__init__.py +33 -0
- tnfr/core/container.py +226 -0
- tnfr/core/default_implementations.py +329 -0
- tnfr/core/interfaces.py +279 -0
- tnfr/dynamics/__init__.py +213 -633
- tnfr/dynamics/__init__.pyi +83 -0
- tnfr/dynamics/adaptation.py +267 -0
- tnfr/dynamics/adaptation.pyi +7 -0
- tnfr/dynamics/adaptive_sequences.py +189 -0
- tnfr/dynamics/adaptive_sequences.pyi +14 -0
- tnfr/dynamics/aliases.py +23 -0
- tnfr/dynamics/aliases.pyi +19 -0
- tnfr/dynamics/bifurcation.py +232 -0
- tnfr/dynamics/canonical.py +229 -0
- tnfr/dynamics/canonical.pyi +48 -0
- tnfr/dynamics/coordination.py +385 -0
- tnfr/dynamics/coordination.pyi +25 -0
- tnfr/dynamics/dnfr.py +2699 -398
- tnfr/dynamics/dnfr.pyi +26 -0
- tnfr/dynamics/dynamic_limits.py +225 -0
- tnfr/dynamics/feedback.py +252 -0
- tnfr/dynamics/feedback.pyi +24 -0
- tnfr/dynamics/fused_dnfr.py +454 -0
- tnfr/dynamics/homeostasis.py +157 -0
- tnfr/dynamics/homeostasis.pyi +14 -0
- tnfr/dynamics/integrators.py +496 -102
- tnfr/dynamics/integrators.pyi +36 -0
- tnfr/dynamics/learning.py +310 -0
- tnfr/dynamics/learning.pyi +33 -0
- tnfr/dynamics/metabolism.py +254 -0
- tnfr/dynamics/nbody.py +796 -0
- tnfr/dynamics/nbody_tnfr.py +783 -0
- tnfr/dynamics/propagation.py +326 -0
- tnfr/dynamics/runtime.py +908 -0
- tnfr/dynamics/runtime.pyi +77 -0
- tnfr/dynamics/sampling.py +10 -5
- tnfr/dynamics/sampling.pyi +7 -0
- tnfr/dynamics/selectors.py +711 -0
- tnfr/dynamics/selectors.pyi +85 -0
- tnfr/dynamics/structural_clip.py +207 -0
- tnfr/errors/__init__.py +37 -0
- tnfr/errors/contextual.py +492 -0
- tnfr/execution.py +77 -55
- tnfr/execution.pyi +45 -0
- tnfr/extensions/__init__.py +205 -0
- tnfr/extensions/__init__.pyi +18 -0
- tnfr/extensions/base.py +173 -0
- tnfr/extensions/base.pyi +35 -0
- tnfr/extensions/business/__init__.py +71 -0
- tnfr/extensions/business/__init__.pyi +11 -0
- tnfr/extensions/business/cookbook.py +88 -0
- tnfr/extensions/business/cookbook.pyi +8 -0
- tnfr/extensions/business/health_analyzers.py +202 -0
- tnfr/extensions/business/health_analyzers.pyi +9 -0
- tnfr/extensions/business/patterns.py +183 -0
- tnfr/extensions/business/patterns.pyi +8 -0
- tnfr/extensions/medical/__init__.py +73 -0
- tnfr/extensions/medical/__init__.pyi +11 -0
- tnfr/extensions/medical/cookbook.py +88 -0
- tnfr/extensions/medical/cookbook.pyi +8 -0
- tnfr/extensions/medical/health_analyzers.py +181 -0
- tnfr/extensions/medical/health_analyzers.pyi +9 -0
- tnfr/extensions/medical/patterns.py +163 -0
- tnfr/extensions/medical/patterns.pyi +8 -0
- tnfr/flatten.py +29 -50
- tnfr/flatten.pyi +21 -0
- tnfr/gamma.py +66 -53
- tnfr/gamma.pyi +36 -0
- tnfr/glyph_history.py +144 -57
- tnfr/glyph_history.pyi +35 -0
- tnfr/glyph_runtime.py +19 -0
- tnfr/glyph_runtime.pyi +8 -0
- tnfr/immutable.py +70 -30
- tnfr/immutable.pyi +36 -0
- tnfr/initialization.py +22 -16
- tnfr/initialization.pyi +65 -0
- tnfr/io.py +5 -241
- tnfr/io.pyi +13 -0
- tnfr/locking.pyi +7 -0
- tnfr/mathematics/__init__.py +79 -0
- tnfr/mathematics/backend.py +453 -0
- tnfr/mathematics/backend.pyi +99 -0
- tnfr/mathematics/dynamics.py +408 -0
- tnfr/mathematics/dynamics.pyi +90 -0
- tnfr/mathematics/epi.py +391 -0
- tnfr/mathematics/epi.pyi +65 -0
- tnfr/mathematics/generators.py +242 -0
- tnfr/mathematics/generators.pyi +29 -0
- tnfr/mathematics/metrics.py +119 -0
- tnfr/mathematics/metrics.pyi +16 -0
- tnfr/mathematics/operators.py +239 -0
- tnfr/mathematics/operators.pyi +59 -0
- tnfr/mathematics/operators_factory.py +124 -0
- tnfr/mathematics/operators_factory.pyi +11 -0
- tnfr/mathematics/projection.py +87 -0
- tnfr/mathematics/projection.pyi +33 -0
- tnfr/mathematics/runtime.py +182 -0
- tnfr/mathematics/runtime.pyi +64 -0
- tnfr/mathematics/spaces.py +256 -0
- tnfr/mathematics/spaces.pyi +83 -0
- tnfr/mathematics/transforms.py +305 -0
- tnfr/mathematics/transforms.pyi +62 -0
- tnfr/metrics/__init__.py +47 -9
- tnfr/metrics/__init__.pyi +20 -0
- tnfr/metrics/buffer_cache.py +163 -0
- tnfr/metrics/buffer_cache.pyi +24 -0
- tnfr/metrics/cache_utils.py +214 -0
- tnfr/metrics/coherence.py +1510 -330
- tnfr/metrics/coherence.pyi +129 -0
- tnfr/metrics/common.py +23 -16
- tnfr/metrics/common.pyi +35 -0
- tnfr/metrics/core.py +251 -36
- tnfr/metrics/core.pyi +13 -0
- tnfr/metrics/diagnosis.py +709 -110
- tnfr/metrics/diagnosis.pyi +86 -0
- tnfr/metrics/emergence.py +245 -0
- tnfr/metrics/export.py +60 -18
- tnfr/metrics/export.pyi +7 -0
- tnfr/metrics/glyph_timing.py +233 -43
- tnfr/metrics/glyph_timing.pyi +81 -0
- tnfr/metrics/learning_metrics.py +280 -0
- tnfr/metrics/learning_metrics.pyi +21 -0
- tnfr/metrics/phase_coherence.py +351 -0
- tnfr/metrics/phase_compatibility.py +349 -0
- tnfr/metrics/reporting.py +63 -28
- tnfr/metrics/reporting.pyi +25 -0
- tnfr/metrics/sense_index.py +1126 -43
- tnfr/metrics/sense_index.pyi +9 -0
- tnfr/metrics/trig.py +215 -23
- tnfr/metrics/trig.pyi +13 -0
- tnfr/metrics/trig_cache.py +148 -24
- tnfr/metrics/trig_cache.pyi +10 -0
- tnfr/multiscale/__init__.py +32 -0
- tnfr/multiscale/hierarchical.py +517 -0
- tnfr/node.py +646 -140
- tnfr/node.pyi +139 -0
- tnfr/observers.py +160 -45
- tnfr/observers.pyi +31 -0
- tnfr/ontosim.py +23 -19
- tnfr/ontosim.pyi +28 -0
- tnfr/operators/__init__.py +1358 -106
- tnfr/operators/__init__.pyi +31 -0
- tnfr/operators/algebra.py +277 -0
- tnfr/operators/canonical_patterns.py +420 -0
- tnfr/operators/cascade.py +267 -0
- tnfr/operators/cycle_detection.py +358 -0
- tnfr/operators/definitions.py +4108 -0
- tnfr/operators/definitions.pyi +78 -0
- tnfr/operators/grammar.py +1164 -0
- tnfr/operators/grammar.pyi +140 -0
- tnfr/operators/hamiltonian.py +710 -0
- tnfr/operators/health_analyzer.py +809 -0
- tnfr/operators/jitter.py +107 -38
- tnfr/operators/jitter.pyi +11 -0
- tnfr/operators/lifecycle.py +314 -0
- tnfr/operators/metabolism.py +618 -0
- tnfr/operators/metrics.py +2138 -0
- tnfr/operators/network_analysis/__init__.py +27 -0
- tnfr/operators/network_analysis/source_detection.py +186 -0
- tnfr/operators/nodal_equation.py +395 -0
- tnfr/operators/pattern_detection.py +660 -0
- tnfr/operators/patterns.py +669 -0
- tnfr/operators/postconditions/__init__.py +38 -0
- tnfr/operators/postconditions/mutation.py +236 -0
- tnfr/operators/preconditions/__init__.py +1226 -0
- tnfr/operators/preconditions/coherence.py +305 -0
- tnfr/operators/preconditions/dissonance.py +236 -0
- tnfr/operators/preconditions/emission.py +128 -0
- tnfr/operators/preconditions/mutation.py +580 -0
- tnfr/operators/preconditions/reception.py +125 -0
- tnfr/operators/preconditions/resonance.py +364 -0
- tnfr/operators/registry.py +74 -0
- tnfr/operators/registry.pyi +9 -0
- tnfr/operators/remesh.py +1415 -91
- tnfr/operators/remesh.pyi +26 -0
- tnfr/operators/structural_units.py +268 -0
- tnfr/operators/unified_grammar.py +105 -0
- tnfr/parallel/__init__.py +54 -0
- tnfr/parallel/auto_scaler.py +234 -0
- tnfr/parallel/distributed.py +384 -0
- tnfr/parallel/engine.py +238 -0
- tnfr/parallel/gpu_engine.py +420 -0
- tnfr/parallel/monitoring.py +248 -0
- tnfr/parallel/partitioner.py +459 -0
- tnfr/py.typed +0 -0
- tnfr/recipes/__init__.py +22 -0
- tnfr/recipes/cookbook.py +743 -0
- tnfr/rng.py +75 -151
- tnfr/rng.pyi +26 -0
- tnfr/schemas/__init__.py +8 -0
- tnfr/schemas/grammar.json +94 -0
- tnfr/sdk/__init__.py +107 -0
- tnfr/sdk/__init__.pyi +19 -0
- tnfr/sdk/adaptive_system.py +173 -0
- tnfr/sdk/adaptive_system.pyi +21 -0
- tnfr/sdk/builders.py +370 -0
- tnfr/sdk/builders.pyi +51 -0
- tnfr/sdk/fluent.py +1121 -0
- tnfr/sdk/fluent.pyi +74 -0
- tnfr/sdk/templates.py +342 -0
- tnfr/sdk/templates.pyi +41 -0
- tnfr/sdk/utils.py +341 -0
- tnfr/secure_config.py +46 -0
- tnfr/security/__init__.py +70 -0
- tnfr/security/database.py +514 -0
- tnfr/security/subprocess.py +503 -0
- tnfr/security/validation.py +290 -0
- tnfr/selector.py +59 -22
- tnfr/selector.pyi +19 -0
- tnfr/sense.py +92 -67
- tnfr/sense.pyi +23 -0
- tnfr/services/__init__.py +17 -0
- tnfr/services/orchestrator.py +325 -0
- tnfr/sparse/__init__.py +39 -0
- tnfr/sparse/representations.py +492 -0
- tnfr/structural.py +639 -263
- tnfr/structural.pyi +83 -0
- tnfr/telemetry/__init__.py +35 -0
- tnfr/telemetry/cache_metrics.py +226 -0
- tnfr/telemetry/cache_metrics.pyi +64 -0
- tnfr/telemetry/nu_f.py +422 -0
- tnfr/telemetry/nu_f.pyi +108 -0
- tnfr/telemetry/verbosity.py +36 -0
- tnfr/telemetry/verbosity.pyi +15 -0
- tnfr/tokens.py +2 -4
- tnfr/tokens.pyi +36 -0
- tnfr/tools/__init__.py +20 -0
- tnfr/tools/domain_templates.py +478 -0
- tnfr/tools/sequence_generator.py +846 -0
- tnfr/topology/__init__.py +13 -0
- tnfr/topology/asymmetry.py +151 -0
- tnfr/trace.py +300 -126
- tnfr/trace.pyi +42 -0
- tnfr/tutorials/__init__.py +38 -0
- tnfr/tutorials/autonomous_evolution.py +285 -0
- tnfr/tutorials/interactive.py +1576 -0
- tnfr/tutorials/structural_metabolism.py +238 -0
- tnfr/types.py +743 -12
- tnfr/types.pyi +357 -0
- tnfr/units.py +68 -0
- tnfr/units.pyi +13 -0
- tnfr/utils/__init__.py +282 -0
- tnfr/utils/__init__.pyi +215 -0
- tnfr/utils/cache.py +4223 -0
- tnfr/utils/cache.pyi +470 -0
- tnfr/{callback_utils.py → utils/callbacks.py} +26 -39
- tnfr/utils/callbacks.pyi +49 -0
- tnfr/utils/chunks.py +108 -0
- tnfr/utils/chunks.pyi +22 -0
- tnfr/utils/data.py +428 -0
- tnfr/utils/data.pyi +74 -0
- tnfr/utils/graph.py +85 -0
- tnfr/utils/graph.pyi +10 -0
- tnfr/utils/init.py +821 -0
- tnfr/utils/init.pyi +80 -0
- tnfr/utils/io.py +559 -0
- tnfr/utils/io.pyi +66 -0
- tnfr/{helpers → utils}/numeric.py +51 -24
- tnfr/utils/numeric.pyi +21 -0
- tnfr/validation/__init__.py +257 -0
- tnfr/validation/__init__.pyi +85 -0
- tnfr/validation/compatibility.py +460 -0
- tnfr/validation/compatibility.pyi +6 -0
- tnfr/validation/config.py +73 -0
- tnfr/validation/graph.py +139 -0
- tnfr/validation/graph.pyi +18 -0
- tnfr/validation/input_validation.py +755 -0
- tnfr/validation/invariants.py +712 -0
- tnfr/validation/rules.py +253 -0
- tnfr/validation/rules.pyi +44 -0
- tnfr/validation/runtime.py +279 -0
- tnfr/validation/runtime.pyi +28 -0
- tnfr/validation/sequence_validator.py +162 -0
- tnfr/validation/soft_filters.py +170 -0
- tnfr/validation/soft_filters.pyi +32 -0
- tnfr/validation/spectral.py +164 -0
- tnfr/validation/spectral.pyi +42 -0
- tnfr/validation/validator.py +1266 -0
- tnfr/validation/window.py +39 -0
- tnfr/validation/window.pyi +1 -0
- tnfr/visualization/__init__.py +98 -0
- tnfr/visualization/cascade_viz.py +256 -0
- tnfr/visualization/hierarchy.py +284 -0
- tnfr/visualization/sequence_plotter.py +784 -0
- tnfr/viz/__init__.py +60 -0
- tnfr/viz/matplotlib.py +278 -0
- tnfr/viz/matplotlib.pyi +35 -0
- tnfr-8.5.0.dist-info/METADATA +573 -0
- tnfr-8.5.0.dist-info/RECORD +353 -0
- {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/entry_points.txt +1 -0
- {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/licenses/LICENSE.md +1 -1
- tnfr/collections_utils.py +0 -300
- tnfr/config.py +0 -32
- tnfr/grammar.py +0 -344
- tnfr/graph_utils.py +0 -84
- tnfr/helpers/__init__.py +0 -71
- tnfr/import_utils.py +0 -228
- tnfr/json_utils.py +0 -162
- tnfr/logging_utils.py +0 -116
- tnfr/presets.py +0 -60
- 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-8.5.0.dist-info}/WHEEL +0 -0
- {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
"""Contextual error handling for TNFR operations.
|
|
2
|
+
|
|
3
|
+
This module provides enhanced error messages that guide users to solutions
|
|
4
|
+
while maintaining TNFR theoretical compliance. All errors include:
|
|
5
|
+
|
|
6
|
+
1. Clear explanation of the violation
|
|
7
|
+
2. Actionable suggestions for resolution
|
|
8
|
+
3. Links to relevant documentation
|
|
9
|
+
4. Context about the structural operation that failed
|
|
10
|
+
|
|
11
|
+
Canonical Invariants Preserved
|
|
12
|
+
------------------------------
|
|
13
|
+
These errors enforce TNFR invariants from AGENTS.md:
|
|
14
|
+
- Operator closure and sequence validity
|
|
15
|
+
- Phase synchrony requirements for coupling
|
|
16
|
+
- Frequency (νf) bounds in Hz_str units
|
|
17
|
+
- ΔNFR semantic correctness
|
|
18
|
+
- EPI coherence preservation
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from difflib import get_close_matches
|
|
24
|
+
from typing import Optional, List, Dict, Any
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"TNFRUserError",
|
|
28
|
+
"OperatorSequenceError",
|
|
29
|
+
"NetworkConfigError",
|
|
30
|
+
"PhaseError",
|
|
31
|
+
"CoherenceError",
|
|
32
|
+
"FrequencyError",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class TNFRUserError(Exception):
|
|
37
|
+
"""Base class for user-facing TNFR errors with helpful context.
|
|
38
|
+
|
|
39
|
+
All TNFR errors inherit from this class and provide:
|
|
40
|
+
- Human-readable error messages
|
|
41
|
+
- Actionable suggestions
|
|
42
|
+
- Documentation links
|
|
43
|
+
- Structural context
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
message : str
|
|
48
|
+
Primary error message describing what went wrong.
|
|
49
|
+
suggestion : str, optional
|
|
50
|
+
Specific suggestion for how to fix the issue.
|
|
51
|
+
docs_url : str, optional
|
|
52
|
+
URL to relevant documentation section.
|
|
53
|
+
context : dict, optional
|
|
54
|
+
Additional context about the failed operation (node IDs, values, etc).
|
|
55
|
+
|
|
56
|
+
Examples
|
|
57
|
+
--------
|
|
58
|
+
>>> raise TNFRUserError(
|
|
59
|
+
... "Invalid structural frequency",
|
|
60
|
+
... suggestion="νf must be positive in Hz_str units",
|
|
61
|
+
... docs_url="https://tnfr.readthedocs.io/api/core.html#frequency"
|
|
62
|
+
... )
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
def __init__(
|
|
66
|
+
self,
|
|
67
|
+
message: str,
|
|
68
|
+
suggestion: Optional[str] = None,
|
|
69
|
+
docs_url: Optional[str] = None,
|
|
70
|
+
context: Optional[Dict[str, Any]] = None,
|
|
71
|
+
):
|
|
72
|
+
self.message = message
|
|
73
|
+
self.suggestion = suggestion
|
|
74
|
+
self.docs_url = docs_url
|
|
75
|
+
self.context = context or {}
|
|
76
|
+
|
|
77
|
+
# Build comprehensive error message
|
|
78
|
+
full_message = f"\n{'='*70}\n"
|
|
79
|
+
full_message += f"TNFR Error: {message}\n"
|
|
80
|
+
full_message += f"{'='*70}\n"
|
|
81
|
+
|
|
82
|
+
if suggestion:
|
|
83
|
+
full_message += f"\n💡 Suggestion: {suggestion}\n"
|
|
84
|
+
|
|
85
|
+
if context:
|
|
86
|
+
full_message += f"\n📊 Context:\n"
|
|
87
|
+
for key, value in context.items():
|
|
88
|
+
full_message += f" • {key}: {value}\n"
|
|
89
|
+
|
|
90
|
+
if docs_url:
|
|
91
|
+
full_message += f"\n📚 Documentation: {docs_url}\n"
|
|
92
|
+
|
|
93
|
+
full_message += f"{'='*70}\n"
|
|
94
|
+
|
|
95
|
+
super().__init__(full_message)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class OperatorSequenceError(TNFRUserError):
|
|
99
|
+
"""Error raised when operator sequence violates TNFR grammar.
|
|
100
|
+
|
|
101
|
+
TNFR operators must be applied in valid sequences that respect
|
|
102
|
+
structural coherence. This error provides:
|
|
103
|
+
- The invalid sequence attempted
|
|
104
|
+
- Which operator violated the grammar
|
|
105
|
+
- Valid next operators
|
|
106
|
+
- Fuzzy matching for typos
|
|
107
|
+
|
|
108
|
+
Enforces Invariant #4: Operator closure from AGENTS.md
|
|
109
|
+
|
|
110
|
+
Parameters
|
|
111
|
+
----------
|
|
112
|
+
invalid_operator : str
|
|
113
|
+
The operator that violated the grammar.
|
|
114
|
+
sequence_so_far : list of str
|
|
115
|
+
Operators successfully applied before the error.
|
|
116
|
+
valid_next : list of str, optional
|
|
117
|
+
Valid operators that can follow the current sequence.
|
|
118
|
+
|
|
119
|
+
Examples
|
|
120
|
+
--------
|
|
121
|
+
>>> raise OperatorSequenceError(
|
|
122
|
+
... "emision",
|
|
123
|
+
... ["reception", "coherence"],
|
|
124
|
+
... ["emission", "recursivity"]
|
|
125
|
+
... )
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
# Valid TNFR operators (13 canonical operators)
|
|
129
|
+
VALID_OPERATORS = {
|
|
130
|
+
"emission",
|
|
131
|
+
"reception",
|
|
132
|
+
"coherence",
|
|
133
|
+
"dissonance",
|
|
134
|
+
"coupling",
|
|
135
|
+
"resonance",
|
|
136
|
+
"silence",
|
|
137
|
+
"expansion",
|
|
138
|
+
"contraction",
|
|
139
|
+
"self_organization",
|
|
140
|
+
"mutation",
|
|
141
|
+
"transition",
|
|
142
|
+
"recursivity",
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
# Operator aliases for user convenience
|
|
146
|
+
OPERATOR_ALIASES = {
|
|
147
|
+
"emit": "emission",
|
|
148
|
+
"receive": "reception",
|
|
149
|
+
"cohere": "coherence",
|
|
150
|
+
"couple": "coupling",
|
|
151
|
+
"resonate": "resonance",
|
|
152
|
+
"silent": "silence",
|
|
153
|
+
"expand": "expansion",
|
|
154
|
+
"contract": "contraction",
|
|
155
|
+
"self_organize": "self_organization",
|
|
156
|
+
"mutate": "mutation",
|
|
157
|
+
"recurse": "recursivity",
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
def __init__(
|
|
161
|
+
self,
|
|
162
|
+
invalid_operator: str,
|
|
163
|
+
sequence_so_far: Optional[List[str]] = None,
|
|
164
|
+
valid_next: Optional[List[str]] = None,
|
|
165
|
+
):
|
|
166
|
+
sequence_so_far = sequence_so_far or []
|
|
167
|
+
|
|
168
|
+
# Try fuzzy matching for typos
|
|
169
|
+
all_valid = list(self.VALID_OPERATORS) + list(self.OPERATOR_ALIASES.keys())
|
|
170
|
+
matches = get_close_matches(invalid_operator, all_valid, n=3, cutoff=0.6)
|
|
171
|
+
|
|
172
|
+
suggestion_parts = []
|
|
173
|
+
if matches:
|
|
174
|
+
suggestion_parts.append(f"Did you mean one of: {', '.join(matches)}?")
|
|
175
|
+
|
|
176
|
+
if valid_next:
|
|
177
|
+
suggestion_parts.append(f"Valid next operators: {', '.join(valid_next)}")
|
|
178
|
+
else:
|
|
179
|
+
suggestion_parts.append(
|
|
180
|
+
f"Use one of the 13 canonical operators: "
|
|
181
|
+
f"{', '.join(sorted(self.VALID_OPERATORS))}"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
suggestion = " ".join(suggestion_parts) if suggestion_parts else None
|
|
185
|
+
|
|
186
|
+
context = {
|
|
187
|
+
"invalid_operator": invalid_operator,
|
|
188
|
+
"sequence_so_far": (
|
|
189
|
+
" → ".join(sequence_so_far) if sequence_so_far else "empty"
|
|
190
|
+
),
|
|
191
|
+
"operator_count": len(sequence_so_far),
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
super().__init__(
|
|
195
|
+
message=f"Invalid operator sequence: '{invalid_operator}' cannot be applied",
|
|
196
|
+
suggestion=suggestion,
|
|
197
|
+
docs_url="https://github.com/fermga/Teoria-de-la-naturaleza-fractal-resonante-TNFR-/blob/main/docs/source/api/operators.md",
|
|
198
|
+
context=context,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class NetworkConfigError(TNFRUserError):
|
|
203
|
+
"""Error raised when network configuration violates TNFR constraints.
|
|
204
|
+
|
|
205
|
+
This error validates configuration parameters and provides valid ranges
|
|
206
|
+
with physical/structural meaning.
|
|
207
|
+
|
|
208
|
+
Enforces multiple invariants:
|
|
209
|
+
- Invariant #2: Structural units (νf in Hz_str)
|
|
210
|
+
- Invariant #5: Phase check requirements
|
|
211
|
+
- Invariant #6: Node birth/collapse conditions
|
|
212
|
+
|
|
213
|
+
Parameters
|
|
214
|
+
----------
|
|
215
|
+
parameter : str
|
|
216
|
+
The configuration parameter that is invalid.
|
|
217
|
+
value : any
|
|
218
|
+
The invalid value provided.
|
|
219
|
+
valid_range : tuple, optional
|
|
220
|
+
Valid range for the parameter (min, max).
|
|
221
|
+
reason : str, optional
|
|
222
|
+
Structural reason for the constraint.
|
|
223
|
+
|
|
224
|
+
Examples
|
|
225
|
+
--------
|
|
226
|
+
>>> raise NetworkConfigError(
|
|
227
|
+
... "vf",
|
|
228
|
+
... -0.5,
|
|
229
|
+
... (0.01, 100.0),
|
|
230
|
+
... "Structural frequency must be positive (Hz_str units)"
|
|
231
|
+
... )
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
# Valid parameter ranges with structural meaning
|
|
235
|
+
PARAMETER_CONSTRAINTS = {
|
|
236
|
+
"vf": {
|
|
237
|
+
"range": (0.01, 100.0),
|
|
238
|
+
"unit": "Hz_str",
|
|
239
|
+
"description": "Structural frequency (reorganization rate)",
|
|
240
|
+
},
|
|
241
|
+
"phase": {
|
|
242
|
+
"range": (0.0, 2 * 3.14159),
|
|
243
|
+
"unit": "radians",
|
|
244
|
+
"description": "Phase angle for network synchrony",
|
|
245
|
+
},
|
|
246
|
+
"coherence": {
|
|
247
|
+
"range": (0.0, 1.0),
|
|
248
|
+
"unit": "dimensionless",
|
|
249
|
+
"description": "Structural stability measure C(t)",
|
|
250
|
+
},
|
|
251
|
+
"delta_nfr": {
|
|
252
|
+
"range": (-10.0, 10.0),
|
|
253
|
+
"unit": "dimensionless",
|
|
254
|
+
"description": "Internal reorganization gradient ΔNFR",
|
|
255
|
+
},
|
|
256
|
+
"epi": {
|
|
257
|
+
"range": (0.0, 1.0),
|
|
258
|
+
"unit": "dimensionless",
|
|
259
|
+
"description": "Primary Information Structure magnitude",
|
|
260
|
+
},
|
|
261
|
+
"edge_probability": {
|
|
262
|
+
"range": (0.0, 1.0),
|
|
263
|
+
"unit": "probability",
|
|
264
|
+
"description": "Network edge connection probability",
|
|
265
|
+
},
|
|
266
|
+
"num_nodes": {
|
|
267
|
+
"range": (1, 100000),
|
|
268
|
+
"unit": "count",
|
|
269
|
+
"description": "Number of nodes in network",
|
|
270
|
+
},
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
def __init__(
|
|
274
|
+
self,
|
|
275
|
+
parameter: str,
|
|
276
|
+
value: Any,
|
|
277
|
+
valid_range: Optional[tuple] = None,
|
|
278
|
+
reason: Optional[str] = None,
|
|
279
|
+
):
|
|
280
|
+
# Get constraint info if available
|
|
281
|
+
constraint_info = self.PARAMETER_CONSTRAINTS.get(parameter)
|
|
282
|
+
|
|
283
|
+
if constraint_info and not valid_range:
|
|
284
|
+
valid_range = constraint_info["range"]
|
|
285
|
+
reason = reason or constraint_info["description"]
|
|
286
|
+
|
|
287
|
+
suggestion_parts = []
|
|
288
|
+
if valid_range:
|
|
289
|
+
min_val, max_val = valid_range
|
|
290
|
+
suggestion_parts.append(
|
|
291
|
+
f"'{parameter}' must be in range [{min_val}, {max_val}]"
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
if constraint_info:
|
|
295
|
+
suggestion_parts.append(f"Unit: {constraint_info['unit']}")
|
|
296
|
+
|
|
297
|
+
if reason:
|
|
298
|
+
suggestion_parts.append(f"Structural meaning: {reason}")
|
|
299
|
+
|
|
300
|
+
context = {
|
|
301
|
+
"parameter": parameter,
|
|
302
|
+
"provided_value": value,
|
|
303
|
+
"valid_range": (
|
|
304
|
+
f"[{valid_range[0]}, {valid_range[1]}]" if valid_range else "see docs"
|
|
305
|
+
),
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
super().__init__(
|
|
309
|
+
message=f"Invalid network configuration for '{parameter}'",
|
|
310
|
+
suggestion=" | ".join(suggestion_parts) if suggestion_parts else None,
|
|
311
|
+
docs_url="https://github.com/fermga/Teoria-de-la-naturaleza-fractal-resonante-TNFR-/blob/main/docs/source/api/overview.md",
|
|
312
|
+
context=context,
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
class PhaseError(TNFRUserError):
|
|
317
|
+
"""Error raised when phase synchrony is violated.
|
|
318
|
+
|
|
319
|
+
TNFR requires explicit phase checking before coupling operations.
|
|
320
|
+
This error indicates phase incompatibility between nodes.
|
|
321
|
+
|
|
322
|
+
Enforces Invariant #5: Phase check from AGENTS.md
|
|
323
|
+
|
|
324
|
+
Parameters
|
|
325
|
+
----------
|
|
326
|
+
node1 : str
|
|
327
|
+
First node ID.
|
|
328
|
+
node2 : str
|
|
329
|
+
Second node ID.
|
|
330
|
+
phase1 : float
|
|
331
|
+
Phase of first node (radians).
|
|
332
|
+
phase2 : float
|
|
333
|
+
Phase of second node (radians).
|
|
334
|
+
threshold : float
|
|
335
|
+
Phase difference threshold for coupling.
|
|
336
|
+
|
|
337
|
+
Examples
|
|
338
|
+
--------
|
|
339
|
+
>>> raise PhaseError("n1", "n2", 0.5, 2.8, 0.5)
|
|
340
|
+
"""
|
|
341
|
+
|
|
342
|
+
def __init__(
|
|
343
|
+
self,
|
|
344
|
+
node1: str,
|
|
345
|
+
node2: str,
|
|
346
|
+
phase1: float,
|
|
347
|
+
phase2: float,
|
|
348
|
+
threshold: float = 0.5,
|
|
349
|
+
):
|
|
350
|
+
phase_diff = abs(phase1 - phase2)
|
|
351
|
+
|
|
352
|
+
suggestion = (
|
|
353
|
+
f"Nodes cannot couple: phase difference ({phase_diff:.3f} rad) "
|
|
354
|
+
f"exceeds threshold ({threshold:.3f} rad). "
|
|
355
|
+
f"Apply phase synchronization or adjust threshold."
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
context = {
|
|
359
|
+
"node1": node1,
|
|
360
|
+
"node2": node2,
|
|
361
|
+
"phase1": f"{phase1:.3f} rad",
|
|
362
|
+
"phase2": f"{phase2:.3f} rad",
|
|
363
|
+
"phase_difference": f"{phase_diff:.3f} rad",
|
|
364
|
+
"threshold": f"{threshold:.3f} rad",
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
super().__init__(
|
|
368
|
+
message=f"Phase synchrony violation between nodes '{node1}' and '{node2}'",
|
|
369
|
+
suggestion=suggestion,
|
|
370
|
+
docs_url="https://github.com/fermga/Teoria-de-la-naturaleza-fractal-resonante-TNFR-/blob/main/GLOSSARY.md#phase",
|
|
371
|
+
context=context,
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
class CoherenceError(TNFRUserError):
|
|
376
|
+
"""Error raised when coherence operations violate monotonicity.
|
|
377
|
+
|
|
378
|
+
Coherence operator must not decrease C(t) except in controlled
|
|
379
|
+
dissonance tests. This error indicates unexpected coherence loss.
|
|
380
|
+
|
|
381
|
+
Enforces Invariant #1: EPI coherent form from AGENTS.md
|
|
382
|
+
|
|
383
|
+
Parameters
|
|
384
|
+
----------
|
|
385
|
+
operation : str
|
|
386
|
+
The operation that caused coherence decrease.
|
|
387
|
+
before : float
|
|
388
|
+
Coherence C(t) before operation.
|
|
389
|
+
after : float
|
|
390
|
+
Coherence C(t) after operation.
|
|
391
|
+
node_id : str, optional
|
|
392
|
+
Node ID if the error is node-specific.
|
|
393
|
+
|
|
394
|
+
Examples
|
|
395
|
+
--------
|
|
396
|
+
>>> raise CoherenceError("coherence", 0.85, 0.42)
|
|
397
|
+
"""
|
|
398
|
+
|
|
399
|
+
def __init__(
|
|
400
|
+
self,
|
|
401
|
+
operation: str,
|
|
402
|
+
before: float,
|
|
403
|
+
after: float,
|
|
404
|
+
node_id: Optional[str] = None,
|
|
405
|
+
):
|
|
406
|
+
decrease = before - after
|
|
407
|
+
percent_loss = (decrease / before * 100) if before > 0 else 0
|
|
408
|
+
|
|
409
|
+
suggestion = (
|
|
410
|
+
f"Coherence decreased by {decrease:.3f} ({percent_loss:.1f}%). "
|
|
411
|
+
f"This violates the coherence monotonicity invariant. "
|
|
412
|
+
f"Check if this is a controlled dissonance test or if "
|
|
413
|
+
f"there's an unexpected structural instability."
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
context = {
|
|
417
|
+
"operation": operation,
|
|
418
|
+
"coherence_before": f"{before:.3f}",
|
|
419
|
+
"coherence_after": f"{after:.3f}",
|
|
420
|
+
"decrease": f"{decrease:.3f}",
|
|
421
|
+
"percent_loss": f"{percent_loss:.1f}%",
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if node_id:
|
|
425
|
+
context["node_id"] = node_id
|
|
426
|
+
|
|
427
|
+
super().__init__(
|
|
428
|
+
message=f"Unexpected coherence decrease during '{operation}'",
|
|
429
|
+
suggestion=suggestion,
|
|
430
|
+
docs_url="https://github.com/fermga/Teoria-de-la-naturaleza-fractal-resonante-TNFR-/blob/main/AGENTS.md#canonical-invariants",
|
|
431
|
+
context=context,
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
class FrequencyError(TNFRUserError):
|
|
436
|
+
"""Error raised when structural frequency νf is invalid.
|
|
437
|
+
|
|
438
|
+
Structural frequency must be positive and expressed in Hz_str
|
|
439
|
+
(structural hertz) units. This error indicates frequency violations.
|
|
440
|
+
|
|
441
|
+
Enforces Invariant #2: Structural units from AGENTS.md
|
|
442
|
+
|
|
443
|
+
Parameters
|
|
444
|
+
----------
|
|
445
|
+
node_id : str
|
|
446
|
+
Node ID with invalid frequency.
|
|
447
|
+
vf : float
|
|
448
|
+
The invalid frequency value.
|
|
449
|
+
operation : str, optional
|
|
450
|
+
Operation that triggered the check.
|
|
451
|
+
|
|
452
|
+
Examples
|
|
453
|
+
--------
|
|
454
|
+
>>> raise FrequencyError("n1", -0.5, "emission")
|
|
455
|
+
"""
|
|
456
|
+
|
|
457
|
+
def __init__(
|
|
458
|
+
self,
|
|
459
|
+
node_id: str,
|
|
460
|
+
vf: float,
|
|
461
|
+
operation: Optional[str] = None,
|
|
462
|
+
):
|
|
463
|
+
if vf <= 0:
|
|
464
|
+
suggestion = (
|
|
465
|
+
f"Structural frequency νf must be positive (Hz_str units). "
|
|
466
|
+
f"Set νf > 0 for node '{node_id}'. "
|
|
467
|
+
f"Typical range: 0.1 to 10.0 Hz_str."
|
|
468
|
+
)
|
|
469
|
+
elif vf > 100:
|
|
470
|
+
suggestion = (
|
|
471
|
+
f"Structural frequency νf = {vf:.3f} Hz_str is very high. "
|
|
472
|
+
f"Typical range: 0.1 to 10.0 Hz_str. "
|
|
473
|
+
f"Verify this is intentional."
|
|
474
|
+
)
|
|
475
|
+
else:
|
|
476
|
+
suggestion = f"Verify structural frequency for node '{node_id}'."
|
|
477
|
+
|
|
478
|
+
context = {
|
|
479
|
+
"node_id": node_id,
|
|
480
|
+
"vf": f"{vf:.3f} Hz_str",
|
|
481
|
+
"valid_range": "[0.01, 100.0] Hz_str",
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if operation:
|
|
485
|
+
context["operation"] = operation
|
|
486
|
+
|
|
487
|
+
super().__init__(
|
|
488
|
+
message=f"Invalid structural frequency for node '{node_id}'",
|
|
489
|
+
suggestion=suggestion,
|
|
490
|
+
docs_url="https://github.com/fermga/Teoria-de-la-naturaleza-fractal-resonante-TNFR-/blob/main/GLOSSARY.md#structural-frequency",
|
|
491
|
+
context=context,
|
|
492
|
+
)
|