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
tnfr/core/container.py
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"""Dependency injection container for TNFR engine components.
|
|
2
|
+
|
|
3
|
+
This module provides a lightweight dependency injection container that allows
|
|
4
|
+
configuring and resolving engine components (validators, registries, dynamics
|
|
5
|
+
engines, telemetry collectors) without hard-coding implementations.
|
|
6
|
+
|
|
7
|
+
The container supports both singleton and factory registrations, enabling
|
|
8
|
+
flexible composition of TNFR services while maintaining clean separation of
|
|
9
|
+
concerns.
|
|
10
|
+
|
|
11
|
+
Examples
|
|
12
|
+
--------
|
|
13
|
+
Create a container with default implementations:
|
|
14
|
+
|
|
15
|
+
>>> container = TNFRContainer.create_default()
|
|
16
|
+
>>> validator = container.get(ValidationService)
|
|
17
|
+
>>> validator.validate_sequence(["emission", "coherence"])
|
|
18
|
+
|
|
19
|
+
Register custom implementations:
|
|
20
|
+
|
|
21
|
+
>>> container = TNFRContainer()
|
|
22
|
+
>>> container.register_singleton(ValidationService, CustomValidator())
|
|
23
|
+
>>> validator = container.get(ValidationService)
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
from typing import Any, Callable, TypeVar
|
|
29
|
+
|
|
30
|
+
T = TypeVar("T")
|
|
31
|
+
|
|
32
|
+
__all__ = ("TNFRContainer",)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TNFRContainer:
|
|
36
|
+
"""Dependency injection container for TNFR engine components.
|
|
37
|
+
|
|
38
|
+
The container manages the lifecycle of engine services, allowing
|
|
39
|
+
registration of singletons (reused instances) or factories (fresh
|
|
40
|
+
instances on each request). This enables flexible configuration without
|
|
41
|
+
coupling client code to specific implementations.
|
|
42
|
+
|
|
43
|
+
Examples
|
|
44
|
+
--------
|
|
45
|
+
Basic usage with singleton registration:
|
|
46
|
+
|
|
47
|
+
>>> from tnfr.core.interfaces import ValidationService
|
|
48
|
+
>>> class MyValidator:
|
|
49
|
+
... def validate_sequence(self, seq):
|
|
50
|
+
... pass
|
|
51
|
+
... def validate_graph_state(self, graph):
|
|
52
|
+
... pass
|
|
53
|
+
>>> container = TNFRContainer()
|
|
54
|
+
>>> container.register_singleton(ValidationService, MyValidator())
|
|
55
|
+
>>> validator = container.get(ValidationService)
|
|
56
|
+
|
|
57
|
+
Factory registration for per-request instances:
|
|
58
|
+
|
|
59
|
+
>>> container.register_factory(ValidationService, MyValidator)
|
|
60
|
+
>>> v1 = container.get(ValidationService)
|
|
61
|
+
>>> v2 = container.get(ValidationService)
|
|
62
|
+
>>> v1 is not v2 # Different instances
|
|
63
|
+
True
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
def __init__(self) -> None:
|
|
67
|
+
"""Initialize an empty container."""
|
|
68
|
+
self._instances: dict[Any, Any] = {}
|
|
69
|
+
self._factories: dict[Any, Callable[[], Any]] = {}
|
|
70
|
+
self._is_singleton: dict[Any, bool] = {} # Track singleton status
|
|
71
|
+
|
|
72
|
+
def register_singleton(self, interface: type[T], implementation: T) -> None:
|
|
73
|
+
"""Register an implementation as a singleton.
|
|
74
|
+
|
|
75
|
+
The provided instance will be cached and returned for all subsequent
|
|
76
|
+
requests for this interface.
|
|
77
|
+
|
|
78
|
+
Parameters
|
|
79
|
+
----------
|
|
80
|
+
interface : type
|
|
81
|
+
The interface or abstract type to register against.
|
|
82
|
+
implementation : T
|
|
83
|
+
The concrete instance to return for this interface.
|
|
84
|
+
|
|
85
|
+
Examples
|
|
86
|
+
--------
|
|
87
|
+
>>> container = TNFRContainer()
|
|
88
|
+
>>> container.register_singleton(ValidationService, MyValidator())
|
|
89
|
+
"""
|
|
90
|
+
# Store as a factory that returns the same instance
|
|
91
|
+
self._factories[interface] = lambda: implementation
|
|
92
|
+
self._is_singleton[interface] = True
|
|
93
|
+
|
|
94
|
+
def register_factory(
|
|
95
|
+
self, interface: type[T], factory_func: Callable[[], T]
|
|
96
|
+
) -> None:
|
|
97
|
+
"""Register a factory function for creating instances.
|
|
98
|
+
|
|
99
|
+
The factory will be called each time the interface is requested,
|
|
100
|
+
allowing fresh instances or cached instances depending on the
|
|
101
|
+
factory implementation.
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
interface : type
|
|
106
|
+
The interface or abstract type to register against.
|
|
107
|
+
factory_func : callable
|
|
108
|
+
Function that creates and returns an instance of the interface.
|
|
109
|
+
|
|
110
|
+
Examples
|
|
111
|
+
--------
|
|
112
|
+
>>> container = TNFRContainer()
|
|
113
|
+
>>> container.register_factory(ValidationService, MyValidator)
|
|
114
|
+
"""
|
|
115
|
+
self._factories[interface] = factory_func
|
|
116
|
+
self._is_singleton[interface] = False
|
|
117
|
+
|
|
118
|
+
def get(self, interface: type[T]) -> T:
|
|
119
|
+
"""Retrieve an instance implementing the specified interface.
|
|
120
|
+
|
|
121
|
+
For singleton registrations, returns the cached instance. For factory
|
|
122
|
+
registrations, calls the factory to produce an instance.
|
|
123
|
+
|
|
124
|
+
Parameters
|
|
125
|
+
----------
|
|
126
|
+
interface : type
|
|
127
|
+
The interface type to resolve.
|
|
128
|
+
|
|
129
|
+
Returns
|
|
130
|
+
-------
|
|
131
|
+
T
|
|
132
|
+
Instance implementing the interface.
|
|
133
|
+
|
|
134
|
+
Raises
|
|
135
|
+
------
|
|
136
|
+
ValueError
|
|
137
|
+
When no factory is registered for the interface.
|
|
138
|
+
|
|
139
|
+
Examples
|
|
140
|
+
--------
|
|
141
|
+
>>> container = TNFRContainer()
|
|
142
|
+
>>> container.register_singleton(ValidationService, MyValidator())
|
|
143
|
+
>>> validator = container.get(ValidationService)
|
|
144
|
+
"""
|
|
145
|
+
# Check if we have a cached singleton instance
|
|
146
|
+
if interface in self._instances:
|
|
147
|
+
return self._instances[interface]
|
|
148
|
+
|
|
149
|
+
# Check if we have a factory registered
|
|
150
|
+
if interface not in self._factories:
|
|
151
|
+
raise ValueError(
|
|
152
|
+
f"No factory registered for {interface}. "
|
|
153
|
+
f"Use register_singleton() or register_factory() first."
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# Call factory
|
|
157
|
+
instance = self._factories[interface]()
|
|
158
|
+
|
|
159
|
+
# Cache only if registered as singleton
|
|
160
|
+
if self._is_singleton.get(interface, False):
|
|
161
|
+
self._instances[interface] = instance
|
|
162
|
+
|
|
163
|
+
return instance
|
|
164
|
+
|
|
165
|
+
def has(self, interface: type) -> bool:
|
|
166
|
+
"""Check if an interface has a registered factory.
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
interface : type
|
|
171
|
+
The interface type to check.
|
|
172
|
+
|
|
173
|
+
Returns
|
|
174
|
+
-------
|
|
175
|
+
bool
|
|
176
|
+
True if a factory is registered for this interface.
|
|
177
|
+
"""
|
|
178
|
+
return interface in self._factories
|
|
179
|
+
|
|
180
|
+
@classmethod
|
|
181
|
+
def create_default(cls) -> TNFRContainer:
|
|
182
|
+
"""Create a container with default TNFR implementations.
|
|
183
|
+
|
|
184
|
+
This factory method registers the standard implementations of all
|
|
185
|
+
core interfaces, making it easy to get started with the TNFR engine
|
|
186
|
+
without manual configuration.
|
|
187
|
+
|
|
188
|
+
Returns
|
|
189
|
+
-------
|
|
190
|
+
TNFRContainer
|
|
191
|
+
Container configured with default implementations.
|
|
192
|
+
|
|
193
|
+
Examples
|
|
194
|
+
--------
|
|
195
|
+
>>> container = TNFRContainer.create_default()
|
|
196
|
+
>>> validator = container.get(ValidationService)
|
|
197
|
+
>>> # Use validator with default implementation
|
|
198
|
+
|
|
199
|
+
Notes
|
|
200
|
+
-----
|
|
201
|
+
The default implementations are imported lazily to avoid circular
|
|
202
|
+
dependencies. Custom implementations can be registered after creation
|
|
203
|
+
to override defaults.
|
|
204
|
+
"""
|
|
205
|
+
from .default_implementations import (
|
|
206
|
+
DefaultDynamicsEngine,
|
|
207
|
+
DefaultOperatorRegistry,
|
|
208
|
+
DefaultTelemetryCollector,
|
|
209
|
+
DefaultValidationService,
|
|
210
|
+
)
|
|
211
|
+
from .interfaces import (
|
|
212
|
+
DynamicsEngine,
|
|
213
|
+
OperatorRegistry,
|
|
214
|
+
TelemetryCollector,
|
|
215
|
+
ValidationService,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
container = cls()
|
|
219
|
+
|
|
220
|
+
# Register default implementations as singletons
|
|
221
|
+
container.register_singleton(ValidationService, DefaultValidationService())
|
|
222
|
+
container.register_singleton(OperatorRegistry, DefaultOperatorRegistry())
|
|
223
|
+
container.register_singleton(DynamicsEngine, DefaultDynamicsEngine())
|
|
224
|
+
container.register_singleton(TelemetryCollector, DefaultTelemetryCollector())
|
|
225
|
+
|
|
226
|
+
return container
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"""Default implementations of TNFR core interfaces.
|
|
2
|
+
|
|
3
|
+
This module provides concrete implementations of the architectural interfaces
|
|
4
|
+
that wrap existing TNFR functionality. These implementations maintain backward
|
|
5
|
+
compatibility while enabling the new modular architecture.
|
|
6
|
+
|
|
7
|
+
Classes
|
|
8
|
+
-------
|
|
9
|
+
DefaultValidationService
|
|
10
|
+
Wraps tnfr.validation for sequence and graph validation.
|
|
11
|
+
DefaultOperatorRegistry
|
|
12
|
+
Wraps tnfr.operators.registry for operator management.
|
|
13
|
+
DefaultDynamicsEngine
|
|
14
|
+
Wraps tnfr.dynamics for ΔNFR computation and integration.
|
|
15
|
+
DefaultTelemetryCollector
|
|
16
|
+
Wraps tnfr.metrics for coherence and sense index computation.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from contextlib import contextmanager
|
|
22
|
+
from typing import TYPE_CHECKING, Any
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from ..types import TNFRGraph
|
|
26
|
+
from ..operators.definitions import Operator
|
|
27
|
+
|
|
28
|
+
__all__ = (
|
|
29
|
+
"DefaultValidationService",
|
|
30
|
+
"DefaultOperatorRegistry",
|
|
31
|
+
"DefaultDynamicsEngine",
|
|
32
|
+
"DefaultTelemetryCollector",
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class DefaultValidationService:
|
|
37
|
+
"""Default implementation of ValidationService using tnfr.validation.
|
|
38
|
+
|
|
39
|
+
This implementation wraps the existing validation infrastructure to
|
|
40
|
+
provide the ValidationService interface without modifying existing code.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def validate_sequence(self, sequence: list[str]) -> None:
|
|
44
|
+
"""Validate operator sequence using canonical grammar rules.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
sequence : list of str
|
|
49
|
+
Operator tokens to validate.
|
|
50
|
+
|
|
51
|
+
Raises
|
|
52
|
+
------
|
|
53
|
+
ValueError
|
|
54
|
+
When sequence violates TNFR grammar or operator closure.
|
|
55
|
+
"""
|
|
56
|
+
from ..validation import validate_sequence as _validate_sequence
|
|
57
|
+
|
|
58
|
+
# validate_sequence returns ValidationOutcome
|
|
59
|
+
outcome = _validate_sequence(sequence)
|
|
60
|
+
if not outcome.passed:
|
|
61
|
+
summary_message = outcome.summary.get("message", "validation failed")
|
|
62
|
+
raise ValueError(f"Invalid sequence: {summary_message}")
|
|
63
|
+
|
|
64
|
+
def validate_graph_state(self, graph: TNFRGraph) -> None:
|
|
65
|
+
"""Validate graph state using canonical validators.
|
|
66
|
+
|
|
67
|
+
Parameters
|
|
68
|
+
----------
|
|
69
|
+
graph : TNFRGraph
|
|
70
|
+
Graph to validate.
|
|
71
|
+
|
|
72
|
+
Raises
|
|
73
|
+
------
|
|
74
|
+
ValueError
|
|
75
|
+
When graph state violates structural invariants.
|
|
76
|
+
"""
|
|
77
|
+
from ..validation import run_validators
|
|
78
|
+
|
|
79
|
+
# run_validators raises on failure by default
|
|
80
|
+
run_validators(graph)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class DefaultOperatorRegistry:
|
|
84
|
+
"""Default implementation of OperatorRegistry using tnfr.operators.
|
|
85
|
+
|
|
86
|
+
This implementation wraps the global OPERATORS registry to provide
|
|
87
|
+
the OperatorRegistry interface.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
def get_operator(self, token: str) -> Operator:
|
|
91
|
+
"""Retrieve operator by token from global registry.
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
token : str
|
|
96
|
+
Operator identifier.
|
|
97
|
+
|
|
98
|
+
Returns
|
|
99
|
+
-------
|
|
100
|
+
Operator
|
|
101
|
+
The structural operator implementation (class, not instance).
|
|
102
|
+
|
|
103
|
+
Raises
|
|
104
|
+
------
|
|
105
|
+
KeyError
|
|
106
|
+
When token is not registered.
|
|
107
|
+
"""
|
|
108
|
+
from ..operators.registry import get_operator_class
|
|
109
|
+
|
|
110
|
+
# get_operator_class returns the operator class
|
|
111
|
+
return get_operator_class(token)
|
|
112
|
+
|
|
113
|
+
def register_operator(self, operator: Operator) -> None:
|
|
114
|
+
"""Register operator in global registry.
|
|
115
|
+
|
|
116
|
+
Parameters
|
|
117
|
+
----------
|
|
118
|
+
operator : Operator
|
|
119
|
+
Operator to register.
|
|
120
|
+
"""
|
|
121
|
+
from ..operators.registry import OPERATORS
|
|
122
|
+
|
|
123
|
+
# Register by operator name
|
|
124
|
+
OPERATORS[operator.name] = operator.__class__
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class DefaultDynamicsEngine:
|
|
128
|
+
"""Default implementation of DynamicsEngine using tnfr.dynamics.
|
|
129
|
+
|
|
130
|
+
This implementation wraps existing dynamics functions to provide
|
|
131
|
+
the DynamicsEngine interface.
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
def update_delta_nfr(self, graph: TNFRGraph) -> None:
|
|
135
|
+
"""Compute ΔNFR using configured hook.
|
|
136
|
+
|
|
137
|
+
Parameters
|
|
138
|
+
----------
|
|
139
|
+
graph : TNFRGraph
|
|
140
|
+
Graph to update.
|
|
141
|
+
"""
|
|
142
|
+
# Get the configured ΔNFR hook from graph metadata
|
|
143
|
+
compute = graph.graph.get("compute_delta_nfr")
|
|
144
|
+
if callable(compute):
|
|
145
|
+
compute(graph)
|
|
146
|
+
|
|
147
|
+
def integrate_nodal_equation(self, graph: TNFRGraph) -> None:
|
|
148
|
+
"""Integrate nodal equation to update EPI.
|
|
149
|
+
|
|
150
|
+
Parameters
|
|
151
|
+
----------
|
|
152
|
+
graph : TNFRGraph
|
|
153
|
+
Graph to integrate.
|
|
154
|
+
"""
|
|
155
|
+
from ..dynamics.integrators import update_epi_via_nodal_equation
|
|
156
|
+
|
|
157
|
+
# Use default integration parameters from graph
|
|
158
|
+
dt = graph.graph.get("dt", 0.1)
|
|
159
|
+
update_epi_via_nodal_equation(graph, dt=dt)
|
|
160
|
+
|
|
161
|
+
def coordinate_phase_coupling(self, graph: TNFRGraph) -> None:
|
|
162
|
+
"""Coordinate phase synchronization.
|
|
163
|
+
|
|
164
|
+
Parameters
|
|
165
|
+
----------
|
|
166
|
+
graph : TNFRGraph
|
|
167
|
+
Graph whose phase is coordinated.
|
|
168
|
+
"""
|
|
169
|
+
from ..dynamics.coordination import coordinate_global_local_phase
|
|
170
|
+
|
|
171
|
+
# Coordinate phase using default parameters
|
|
172
|
+
coordinate_global_local_phase(graph)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class DefaultTraceContext:
|
|
176
|
+
"""Default trace context for telemetry collection.
|
|
177
|
+
|
|
178
|
+
This context manager captures graph state before and after operator
|
|
179
|
+
application, recording transitions for structural analysis.
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
def __init__(self, graph: TNFRGraph):
|
|
183
|
+
"""Initialize trace context.
|
|
184
|
+
|
|
185
|
+
Parameters
|
|
186
|
+
----------
|
|
187
|
+
graph : TNFRGraph
|
|
188
|
+
Graph being traced.
|
|
189
|
+
"""
|
|
190
|
+
self.graph = graph
|
|
191
|
+
self.transitions: list[dict[str, Any]] = []
|
|
192
|
+
|
|
193
|
+
def __enter__(self):
|
|
194
|
+
"""Enter trace context."""
|
|
195
|
+
return self
|
|
196
|
+
|
|
197
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
198
|
+
"""Exit trace context."""
|
|
199
|
+
# Save transitions when exiting context
|
|
200
|
+
self._save_transitions()
|
|
201
|
+
return False
|
|
202
|
+
|
|
203
|
+
def _save_transitions(self) -> None:
|
|
204
|
+
"""Save transitions to graph metadata."""
|
|
205
|
+
if self.transitions:
|
|
206
|
+
existing = self.graph.graph.get("_trace_transitions", [])
|
|
207
|
+
existing_copy = list(existing) # Make a copy to avoid mutation
|
|
208
|
+
existing_copy.extend(self.transitions)
|
|
209
|
+
self.graph.graph["_trace_transitions"] = existing_copy
|
|
210
|
+
|
|
211
|
+
def capture_state(self, graph: TNFRGraph) -> dict[str, Any]:
|
|
212
|
+
"""Capture current graph state.
|
|
213
|
+
|
|
214
|
+
Parameters
|
|
215
|
+
----------
|
|
216
|
+
graph : TNFRGraph
|
|
217
|
+
Graph to capture.
|
|
218
|
+
|
|
219
|
+
Returns
|
|
220
|
+
-------
|
|
221
|
+
dict
|
|
222
|
+
State snapshot.
|
|
223
|
+
"""
|
|
224
|
+
from ..metrics.common import compute_coherence
|
|
225
|
+
|
|
226
|
+
# Capture key metrics
|
|
227
|
+
return {
|
|
228
|
+
"coherence": compute_coherence(graph),
|
|
229
|
+
"node_count": graph.number_of_nodes(),
|
|
230
|
+
"edge_count": (
|
|
231
|
+
graph.number_of_edges() if hasattr(graph, "number_of_edges") else 0
|
|
232
|
+
),
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
def record_transition(
|
|
236
|
+
self,
|
|
237
|
+
operator_token: str,
|
|
238
|
+
pre_state: dict[str, Any],
|
|
239
|
+
post_state: dict[str, Any],
|
|
240
|
+
) -> None:
|
|
241
|
+
"""Record operator transition.
|
|
242
|
+
|
|
243
|
+
Parameters
|
|
244
|
+
----------
|
|
245
|
+
operator_token : str
|
|
246
|
+
Operator that caused transition.
|
|
247
|
+
pre_state : dict
|
|
248
|
+
State before operator.
|
|
249
|
+
post_state : dict
|
|
250
|
+
State after operator.
|
|
251
|
+
"""
|
|
252
|
+
self.transitions.append(
|
|
253
|
+
{
|
|
254
|
+
"operator": operator_token,
|
|
255
|
+
"pre": pre_state,
|
|
256
|
+
"post": post_state,
|
|
257
|
+
"delta_coherence": post_state["coherence"] - pre_state["coherence"],
|
|
258
|
+
}
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class DefaultTelemetryCollector:
|
|
263
|
+
"""Default implementation of TelemetryCollector using tnfr.metrics.
|
|
264
|
+
|
|
265
|
+
This implementation wraps existing metrics functions to provide
|
|
266
|
+
the TelemetryCollector interface.
|
|
267
|
+
"""
|
|
268
|
+
|
|
269
|
+
@contextmanager
|
|
270
|
+
def trace_context(self, graph: TNFRGraph):
|
|
271
|
+
"""Create trace context for operator execution.
|
|
272
|
+
|
|
273
|
+
Parameters
|
|
274
|
+
----------
|
|
275
|
+
graph : TNFRGraph
|
|
276
|
+
Graph being traced.
|
|
277
|
+
|
|
278
|
+
Yields
|
|
279
|
+
------
|
|
280
|
+
DefaultTraceContext
|
|
281
|
+
Context for capturing transitions.
|
|
282
|
+
"""
|
|
283
|
+
context = DefaultTraceContext(graph)
|
|
284
|
+
try:
|
|
285
|
+
yield context
|
|
286
|
+
finally:
|
|
287
|
+
# Ensure transitions are saved using the helper method
|
|
288
|
+
context._save_transitions()
|
|
289
|
+
|
|
290
|
+
def compute_coherence(self, graph: TNFRGraph) -> float:
|
|
291
|
+
"""Compute global coherence C(t).
|
|
292
|
+
|
|
293
|
+
Parameters
|
|
294
|
+
----------
|
|
295
|
+
graph : TNFRGraph
|
|
296
|
+
Graph to measure.
|
|
297
|
+
|
|
298
|
+
Returns
|
|
299
|
+
-------
|
|
300
|
+
float
|
|
301
|
+
Coherence value in [0, 1].
|
|
302
|
+
"""
|
|
303
|
+
from ..metrics.common import compute_coherence
|
|
304
|
+
|
|
305
|
+
return compute_coherence(graph)
|
|
306
|
+
|
|
307
|
+
def compute_sense_index(self, graph: TNFRGraph) -> dict[str, Any]:
|
|
308
|
+
"""Compute sense index Si.
|
|
309
|
+
|
|
310
|
+
Parameters
|
|
311
|
+
----------
|
|
312
|
+
graph : TNFRGraph
|
|
313
|
+
Graph to measure.
|
|
314
|
+
|
|
315
|
+
Returns
|
|
316
|
+
-------
|
|
317
|
+
dict
|
|
318
|
+
Sense index metrics.
|
|
319
|
+
"""
|
|
320
|
+
from ..metrics.sense_index import compute_Si
|
|
321
|
+
|
|
322
|
+
result = compute_Si(graph)
|
|
323
|
+
|
|
324
|
+
# Ensure we return a dict
|
|
325
|
+
if isinstance(result, dict):
|
|
326
|
+
return result
|
|
327
|
+
else:
|
|
328
|
+
# If compute_Si returns a scalar, wrap it
|
|
329
|
+
return {"Si": result}
|