tnfr 3.0.3__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 +375 -56
- 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 +723 -0
- 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 +171 -0
- tnfr/cache.pyi +13 -0
- tnfr/cli/__init__.py +110 -0
- tnfr/cli/__init__.pyi +26 -0
- tnfr/cli/arguments.py +489 -0
- tnfr/cli/arguments.pyi +29 -0
- tnfr/cli/execution.py +914 -0
- tnfr/cli/execution.pyi +70 -0
- tnfr/cli/interactive_validator.py +614 -0
- tnfr/cli/utils.py +51 -0
- 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/config/constants.py +104 -0
- tnfr/config/constants.pyi +12 -0
- tnfr/config/defaults.py +54 -0
- tnfr/config/defaults_core.py +212 -0
- 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 +92 -0
- tnfr/constants/__init__.pyi +92 -0
- tnfr/constants/aliases.py +33 -0
- tnfr/constants/aliases.pyi +27 -0
- tnfr/constants/init.py +33 -0
- tnfr/constants/init.pyi +12 -0
- tnfr/constants/metric.py +104 -0
- 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 +238 -0
- 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 +3034 -0
- 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 +661 -0
- 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 +36 -0
- 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 +223 -0
- 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 +262 -0
- tnfr/flatten.pyi +21 -0
- tnfr/gamma.py +354 -0
- tnfr/gamma.pyi +36 -0
- tnfr/glyph_history.py +377 -0
- tnfr/glyph_history.pyi +35 -0
- tnfr/glyph_runtime.py +19 -0
- tnfr/glyph_runtime.pyi +8 -0
- tnfr/immutable.py +218 -0
- tnfr/immutable.pyi +36 -0
- tnfr/initialization.py +203 -0
- tnfr/initialization.pyi +65 -0
- tnfr/io.py +10 -0
- tnfr/io.pyi +13 -0
- tnfr/locking.py +37 -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 +79 -0
- 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 +2009 -0
- tnfr/metrics/coherence.pyi +129 -0
- tnfr/metrics/common.py +158 -0
- tnfr/metrics/common.pyi +35 -0
- tnfr/metrics/core.py +316 -0
- tnfr/metrics/core.pyi +13 -0
- tnfr/metrics/diagnosis.py +833 -0
- tnfr/metrics/diagnosis.pyi +86 -0
- tnfr/metrics/emergence.py +245 -0
- tnfr/metrics/export.py +179 -0
- tnfr/metrics/export.pyi +7 -0
- tnfr/metrics/glyph_timing.py +379 -0
- 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 +183 -0
- tnfr/metrics/reporting.pyi +25 -0
- tnfr/metrics/sense_index.py +1203 -0
- tnfr/metrics/sense_index.pyi +9 -0
- tnfr/metrics/trig.py +373 -0
- tnfr/metrics/trig.pyi +13 -0
- tnfr/metrics/trig_cache.py +233 -0
- tnfr/metrics/trig_cache.pyi +10 -0
- tnfr/multiscale/__init__.py +32 -0
- tnfr/multiscale/hierarchical.py +517 -0
- tnfr/node.py +763 -0
- tnfr/node.pyi +139 -0
- tnfr/observers.py +255 -130
- tnfr/observers.pyi +31 -0
- tnfr/ontosim.py +144 -137
- tnfr/ontosim.pyi +28 -0
- tnfr/operators/__init__.py +1672 -0
- 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 +272 -0
- 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 +1809 -0
- 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 +178 -0
- 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 +247 -0
- tnfr/selector.pyi +19 -0
- tnfr/sense.py +378 -0
- 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 +705 -0
- 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 +58 -0
- 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 +543 -0
- 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 +775 -0
- 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/utils/callbacks.py +375 -0
- 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/utils/numeric.py +114 -0
- 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-8.5.0.dist-info/entry_points.txt +3 -0
- tnfr-3.0.3.dist-info/licenses/LICENSE.txt → tnfr-8.5.0.dist-info/licenses/LICENSE.md +1 -1
- tnfr/constants.py +0 -183
- tnfr/dynamics.py +0 -543
- tnfr/helpers.py +0 -198
- tnfr/main.py +0 -37
- tnfr/operators.py +0 -296
- tnfr-3.0.3.dist-info/METADATA +0 -35
- tnfr-3.0.3.dist-info/RECORD +0 -13
- {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
- {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
"""Cycle detection and validation for regenerative TNFR sequences.
|
|
2
|
+
|
|
3
|
+
This module implements R5_REGENERATIVE_CYCLES validation, ensuring that
|
|
4
|
+
regenerative cycles are structurally valid and self-sustaining according
|
|
5
|
+
to TNFR canonical principles.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from enum import Enum
|
|
11
|
+
from typing import TYPE_CHECKING, Any, Sequence
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from .grammar import StructuralPattern
|
|
15
|
+
|
|
16
|
+
from ..compat.dataclass import dataclass
|
|
17
|
+
from ..config.operator_names import (
|
|
18
|
+
COHERENCE,
|
|
19
|
+
COUPLING,
|
|
20
|
+
EMISSION,
|
|
21
|
+
RECEPTION,
|
|
22
|
+
RECURSIVITY,
|
|
23
|
+
RESONANCE,
|
|
24
|
+
SELF_ORGANIZATION,
|
|
25
|
+
SILENCE,
|
|
26
|
+
TRANSITION,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Define stabilizers using canonical operator names (not glyph codes)
|
|
30
|
+
# These operators provide structural stability in TNFR sequences.
|
|
31
|
+
# Note: This uses canonical names (coherence, resonance, etc.) rather than
|
|
32
|
+
# glyph codes (IL, RA, etc.) from config.constants.STABILIZERS to match
|
|
33
|
+
# the sequence validation format throughout the system.
|
|
34
|
+
_STABILIZERS_SET = frozenset(
|
|
35
|
+
[COHERENCE, SELF_ORGANIZATION, SILENCE, RESONANCE, COUPLING]
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"REGENERATORS",
|
|
40
|
+
"MIN_CYCLE_LENGTH",
|
|
41
|
+
"MAX_CYCLE_LENGTH",
|
|
42
|
+
"CycleType",
|
|
43
|
+
"CycleAnalysis",
|
|
44
|
+
"CycleDetector",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
# Regenerators: operators that enable structural renewal and regeneration
|
|
48
|
+
REGENERATORS = [TRANSITION, RECURSIVITY, SILENCE] # NAV, REMESH, SHA
|
|
49
|
+
|
|
50
|
+
# Cycle length constraints
|
|
51
|
+
MIN_CYCLE_LENGTH = 5 # Minimum operators for meaningful cyclic behavior
|
|
52
|
+
MAX_CYCLE_LENGTH = 13 # Maximum = all canonical operators once
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class CycleType(Enum):
|
|
56
|
+
"""Types of regenerative cycles based on dominant regenerator."""
|
|
57
|
+
|
|
58
|
+
LINEAR = "linear" # Traditional non-cyclic sequence
|
|
59
|
+
REGENERATIVE = "regenerative" # Cycle with regenerators
|
|
60
|
+
RECURSIVE = "recursive" # REMESH-driven (fractal regeneration)
|
|
61
|
+
MEDITATIVE = "meditative" # SHA-driven (paused renewal)
|
|
62
|
+
TRANSFORMATIVE = "transformative" # NAV-driven (phase transition)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass(slots=True)
|
|
66
|
+
class CycleAnalysis:
|
|
67
|
+
"""Results of regenerative cycle analysis."""
|
|
68
|
+
|
|
69
|
+
is_valid_regenerative: bool
|
|
70
|
+
reason: str = ""
|
|
71
|
+
cycle_type: CycleType = CycleType.LINEAR
|
|
72
|
+
health_score: float = 0.0
|
|
73
|
+
regenerator_position: int = -1
|
|
74
|
+
stabilizer_count_before: int = 0
|
|
75
|
+
stabilizer_count_after: int = 0
|
|
76
|
+
balance_score: float = 0.0
|
|
77
|
+
diversity_score: float = 0.0
|
|
78
|
+
coherence_score: float = 0.0
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class CycleDetector:
|
|
82
|
+
"""Detects and validates regenerative cycles in TNFR sequences.
|
|
83
|
+
|
|
84
|
+
Implements R5_REGENERATIVE_CYCLES validation rules:
|
|
85
|
+
- Cycles must have minimum length (MIN_CYCLE_LENGTH)
|
|
86
|
+
- Must include stabilizers before AND after regenerator
|
|
87
|
+
- Must achieve minimum structural health score (>0.6)
|
|
88
|
+
- Validates balance, diversity, and coherence
|
|
89
|
+
|
|
90
|
+
Note: Uses _STABILIZERS_SET with canonical operator names to match
|
|
91
|
+
the sequence validation format. Reuses pattern detector methods for
|
|
92
|
+
balance, diversity, and health calculations to avoid code duplication.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
# Minimum health score for valid regenerative cycle
|
|
96
|
+
MIN_HEALTH_SCORE = 0.6
|
|
97
|
+
|
|
98
|
+
def analyze_potential_cycle(
|
|
99
|
+
self, sequence: Sequence[str], regenerator_index: int
|
|
100
|
+
) -> CycleAnalysis:
|
|
101
|
+
"""Analyze if a regenerator creates a valid regenerative cycle.
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
sequence : Sequence[str]
|
|
106
|
+
Complete operator sequence (canonical names).
|
|
107
|
+
regenerator_index : int
|
|
108
|
+
Position of the regenerator operator.
|
|
109
|
+
|
|
110
|
+
Returns
|
|
111
|
+
-------
|
|
112
|
+
CycleAnalysis
|
|
113
|
+
Detailed analysis of cycle validity and characteristics.
|
|
114
|
+
"""
|
|
115
|
+
# 1. Check minimum length
|
|
116
|
+
if len(sequence) < MIN_CYCLE_LENGTH:
|
|
117
|
+
return CycleAnalysis(
|
|
118
|
+
is_valid_regenerative=False,
|
|
119
|
+
reason="too_short",
|
|
120
|
+
cycle_type=CycleType.LINEAR,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# 2. Check maximum length
|
|
124
|
+
if len(sequence) > MAX_CYCLE_LENGTH:
|
|
125
|
+
return CycleAnalysis(
|
|
126
|
+
is_valid_regenerative=False,
|
|
127
|
+
reason="too_long",
|
|
128
|
+
cycle_type=CycleType.LINEAR,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
# 3. Verify regenerator is valid
|
|
132
|
+
if regenerator_index < 0 or regenerator_index >= len(sequence):
|
|
133
|
+
return CycleAnalysis(
|
|
134
|
+
is_valid_regenerative=False,
|
|
135
|
+
reason="invalid_regenerator_position",
|
|
136
|
+
cycle_type=CycleType.LINEAR,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
regenerator = sequence[regenerator_index]
|
|
140
|
+
if regenerator not in REGENERATORS:
|
|
141
|
+
return CycleAnalysis(
|
|
142
|
+
is_valid_regenerative=False,
|
|
143
|
+
reason="not_a_regenerator",
|
|
144
|
+
cycle_type=CycleType.LINEAR,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# 4. Check stabilizers before and after regenerator
|
|
148
|
+
before_segment = sequence[:regenerator_index]
|
|
149
|
+
after_segment = sequence[regenerator_index + 1 :]
|
|
150
|
+
|
|
151
|
+
stabilizers_before = self._count_stabilizers(before_segment)
|
|
152
|
+
stabilizers_after = self._count_stabilizers(after_segment)
|
|
153
|
+
|
|
154
|
+
if stabilizers_before == 0 or stabilizers_after == 0:
|
|
155
|
+
return CycleAnalysis(
|
|
156
|
+
is_valid_regenerative=False,
|
|
157
|
+
reason="no_stabilization",
|
|
158
|
+
cycle_type=CycleType.LINEAR,
|
|
159
|
+
stabilizer_count_before=stabilizers_before,
|
|
160
|
+
stabilizer_count_after=stabilizers_after,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# 5. Calculate structural health
|
|
164
|
+
balance = self._calculate_balance(sequence)
|
|
165
|
+
diversity = self._calculate_diversity(sequence)
|
|
166
|
+
coherence = self._calculate_sequence_coherence(sequence)
|
|
167
|
+
|
|
168
|
+
health_score = (balance + diversity + coherence) / 3.0
|
|
169
|
+
|
|
170
|
+
# 6. Determine cycle type
|
|
171
|
+
cycle_type = self._determine_cycle_type(regenerator)
|
|
172
|
+
|
|
173
|
+
# 7. Validate health threshold
|
|
174
|
+
is_valid = health_score >= self.MIN_HEALTH_SCORE
|
|
175
|
+
|
|
176
|
+
return CycleAnalysis(
|
|
177
|
+
is_valid_regenerative=is_valid,
|
|
178
|
+
reason="valid" if is_valid else "low_health_score",
|
|
179
|
+
cycle_type=cycle_type,
|
|
180
|
+
health_score=health_score,
|
|
181
|
+
regenerator_position=regenerator_index,
|
|
182
|
+
stabilizer_count_before=stabilizers_before,
|
|
183
|
+
stabilizer_count_after=stabilizers_after,
|
|
184
|
+
balance_score=balance,
|
|
185
|
+
diversity_score=diversity,
|
|
186
|
+
coherence_score=coherence,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
def analyze_full_cycle(self, sequence: Sequence[str]) -> CycleAnalysis:
|
|
190
|
+
"""Analyze complete sequence for regenerative cycle properties.
|
|
191
|
+
|
|
192
|
+
Searches for regenerators in the sequence and validates the
|
|
193
|
+
strongest regenerative cycle found.
|
|
194
|
+
|
|
195
|
+
Parameters
|
|
196
|
+
----------
|
|
197
|
+
sequence : Sequence[str]
|
|
198
|
+
Complete operator sequence (canonical names).
|
|
199
|
+
|
|
200
|
+
Returns
|
|
201
|
+
-------
|
|
202
|
+
CycleAnalysis
|
|
203
|
+
Analysis of the best regenerative cycle found, or
|
|
204
|
+
indication that sequence is not regenerative.
|
|
205
|
+
"""
|
|
206
|
+
if len(sequence) < MIN_CYCLE_LENGTH:
|
|
207
|
+
return CycleAnalysis(
|
|
208
|
+
is_valid_regenerative=False,
|
|
209
|
+
reason="too_short",
|
|
210
|
+
cycle_type=CycleType.LINEAR,
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
# Find all regenerators in sequence
|
|
214
|
+
regenerator_positions = [
|
|
215
|
+
i for i, op in enumerate(sequence) if op in REGENERATORS
|
|
216
|
+
]
|
|
217
|
+
|
|
218
|
+
if not regenerator_positions:
|
|
219
|
+
return CycleAnalysis(
|
|
220
|
+
is_valid_regenerative=False,
|
|
221
|
+
reason="no_regenerator",
|
|
222
|
+
cycle_type=CycleType.LINEAR,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# Analyze each regenerator position and keep best result
|
|
226
|
+
best_analysis = None
|
|
227
|
+
best_health = -1.0
|
|
228
|
+
|
|
229
|
+
for pos in regenerator_positions:
|
|
230
|
+
analysis = self.analyze_potential_cycle(sequence, pos)
|
|
231
|
+
if analysis.health_score > best_health:
|
|
232
|
+
best_health = analysis.health_score
|
|
233
|
+
best_analysis = analysis
|
|
234
|
+
|
|
235
|
+
return best_analysis or CycleAnalysis(
|
|
236
|
+
is_valid_regenerative=False,
|
|
237
|
+
reason="no_valid_cycle",
|
|
238
|
+
cycle_type=CycleType.LINEAR,
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
def _count_stabilizers(self, segment: Sequence[str]) -> int:
|
|
242
|
+
"""Count stabilizing operators in a sequence segment.
|
|
243
|
+
|
|
244
|
+
Uses canonical operator names: coherence, self_organization, silence, resonance, coupling.
|
|
245
|
+
"""
|
|
246
|
+
return sum(1 for op in segment if op in _STABILIZERS_SET)
|
|
247
|
+
|
|
248
|
+
def _calculate_balance(self, sequence: Sequence[str]) -> float:
|
|
249
|
+
"""Calculate structural balance score (0.0-1.0).
|
|
250
|
+
|
|
251
|
+
Reuses the existing pattern detector's health calculation approach
|
|
252
|
+
but adapted for cycle-specific validation. Balance measures equilibrium
|
|
253
|
+
between stabilizing operators.
|
|
254
|
+
"""
|
|
255
|
+
from .patterns import AdvancedPatternDetector
|
|
256
|
+
|
|
257
|
+
if not sequence:
|
|
258
|
+
return 0.0
|
|
259
|
+
|
|
260
|
+
# Use existing pattern detector for consistent health metrics
|
|
261
|
+
detector = AdvancedPatternDetector()
|
|
262
|
+
health_metrics = detector._calculate_health_metrics(sequence)
|
|
263
|
+
|
|
264
|
+
# Adapt balance calculation for cycle validation
|
|
265
|
+
# Cycles need good balance (not too much stabilization, not too chaotic)
|
|
266
|
+
balance_raw = health_metrics.get("balance", 0.0)
|
|
267
|
+
|
|
268
|
+
# Normalize: optimal balance is around 0.2-0.4 (slightly more stabilizers)
|
|
269
|
+
# Convert to 0-1 score where 0.3 is optimal
|
|
270
|
+
if -0.1 <= balance_raw <= 0.5:
|
|
271
|
+
# Good range
|
|
272
|
+
score = 1.0 - abs(balance_raw - 0.3) * 1.5
|
|
273
|
+
else:
|
|
274
|
+
# Outside good range
|
|
275
|
+
score = max(0.0, 0.5 - abs(balance_raw - 0.3) * 0.5)
|
|
276
|
+
|
|
277
|
+
return max(0.0, min(1.0, score))
|
|
278
|
+
|
|
279
|
+
def _calculate_diversity(self, sequence: Sequence[str]) -> float:
|
|
280
|
+
"""Calculate operator diversity score (0.0-1.0).
|
|
281
|
+
|
|
282
|
+
Reuses complexity calculation from AdvancedPatternDetector which
|
|
283
|
+
includes diversity as a component.
|
|
284
|
+
"""
|
|
285
|
+
from .patterns import AdvancedPatternDetector
|
|
286
|
+
|
|
287
|
+
if not sequence:
|
|
288
|
+
return 0.0
|
|
289
|
+
|
|
290
|
+
detector = AdvancedPatternDetector()
|
|
291
|
+
# Complexity includes diversity as a factor
|
|
292
|
+
complexity = detector._calculate_complexity(sequence)
|
|
293
|
+
|
|
294
|
+
# For cycles, we primarily care about diversity component
|
|
295
|
+
unique_count = len(set(sequence))
|
|
296
|
+
total_count = len(sequence)
|
|
297
|
+
diversity_ratio = unique_count / total_count
|
|
298
|
+
|
|
299
|
+
# Bonus for using many unique operators (> 5)
|
|
300
|
+
if unique_count >= 5:
|
|
301
|
+
bonus = min(0.2, (unique_count - 5) * 0.05)
|
|
302
|
+
diversity_ratio = min(1.0, diversity_ratio + bonus)
|
|
303
|
+
|
|
304
|
+
return diversity_ratio
|
|
305
|
+
|
|
306
|
+
def _calculate_sequence_coherence(self, sequence: Sequence[str]) -> float:
|
|
307
|
+
"""Calculate structural coherence score (0.0-1.0).
|
|
308
|
+
|
|
309
|
+
Combines insights from pattern detector with cycle-specific
|
|
310
|
+
coherence requirements (good start/end, essential elements).
|
|
311
|
+
"""
|
|
312
|
+
from .patterns import AdvancedPatternDetector
|
|
313
|
+
|
|
314
|
+
if not sequence:
|
|
315
|
+
return 0.0
|
|
316
|
+
|
|
317
|
+
detector = AdvancedPatternDetector()
|
|
318
|
+
health_metrics = detector._calculate_health_metrics(sequence)
|
|
319
|
+
|
|
320
|
+
score = 0.0
|
|
321
|
+
|
|
322
|
+
# 1. Good start (emission or reception)
|
|
323
|
+
if sequence[0] in {EMISSION, RECEPTION, COHERENCE}:
|
|
324
|
+
score += 0.25
|
|
325
|
+
|
|
326
|
+
# 2. Good ending (check has_closure from health metrics)
|
|
327
|
+
if health_metrics.get("has_closure", False):
|
|
328
|
+
score += 0.25
|
|
329
|
+
|
|
330
|
+
# 3. Contains coupling (network integration)
|
|
331
|
+
if COUPLING in sequence:
|
|
332
|
+
score += 0.15
|
|
333
|
+
|
|
334
|
+
# 4. Contains resonance (amplification)
|
|
335
|
+
if RESONANCE in sequence:
|
|
336
|
+
score += 0.15
|
|
337
|
+
|
|
338
|
+
# 5. Has emission or reception (information flow)
|
|
339
|
+
if EMISSION in sequence or RECEPTION in sequence:
|
|
340
|
+
score += 0.10
|
|
341
|
+
|
|
342
|
+
# 6. Bonus for cyclic closure (starts and ends with stabilizers)
|
|
343
|
+
if len(sequence) >= 2:
|
|
344
|
+
if sequence[0] in _STABILIZERS_SET and sequence[-1] in _STABILIZERS_SET:
|
|
345
|
+
score += 0.10
|
|
346
|
+
|
|
347
|
+
return min(1.0, score)
|
|
348
|
+
|
|
349
|
+
def _determine_cycle_type(self, regenerator: str) -> CycleType:
|
|
350
|
+
"""Determine cycle type based on dominant regenerator."""
|
|
351
|
+
if regenerator == TRANSITION:
|
|
352
|
+
return CycleType.TRANSFORMATIVE # NAV
|
|
353
|
+
elif regenerator == RECURSIVITY:
|
|
354
|
+
return CycleType.RECURSIVE # REMESH
|
|
355
|
+
elif regenerator == SILENCE:
|
|
356
|
+
return CycleType.MEDITATIVE # SHA
|
|
357
|
+
else:
|
|
358
|
+
return CycleType.REGENERATIVE # Generic
|