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,846 @@
|
|
|
1
|
+
"""Context-guided sequence generator for TNFR operator sequences.
|
|
2
|
+
|
|
3
|
+
This module provides intelligent sequence generation capabilities that help
|
|
4
|
+
users construct optimal TNFR operator sequences based on context, objectives,
|
|
5
|
+
and structural constraints. The generator uses domain templates, pattern
|
|
6
|
+
detection, and health analysis to produce high-quality sequences.
|
|
7
|
+
|
|
8
|
+
Examples
|
|
9
|
+
--------
|
|
10
|
+
>>> from tnfr.tools.sequence_generator import ContextualSequenceGenerator
|
|
11
|
+
>>> generator = ContextualSequenceGenerator()
|
|
12
|
+
>>>
|
|
13
|
+
>>> # Generate for specific domain and objective
|
|
14
|
+
>>> seq = generator.generate_for_context(
|
|
15
|
+
... domain="therapeutic",
|
|
16
|
+
... objective="crisis_intervention",
|
|
17
|
+
... min_health=0.75
|
|
18
|
+
... )
|
|
19
|
+
>>> print(seq)
|
|
20
|
+
['emission', 'reception', 'coherence', 'resonance', 'silence']
|
|
21
|
+
>>>
|
|
22
|
+
>>> # Generate to match a specific pattern
|
|
23
|
+
>>> seq = generator.generate_for_pattern(
|
|
24
|
+
... target_pattern="BOOTSTRAP",
|
|
25
|
+
... min_health=0.70
|
|
26
|
+
... )
|
|
27
|
+
>>>
|
|
28
|
+
>>> # Improve an existing sequence
|
|
29
|
+
>>> current = ["emission", "coherence", "silence"]
|
|
30
|
+
>>> improved, recommendations = generator.improve_sequence(current, target_health=0.80)
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from __future__ import annotations
|
|
34
|
+
|
|
35
|
+
import random
|
|
36
|
+
from typing import TYPE_CHECKING
|
|
37
|
+
|
|
38
|
+
if TYPE_CHECKING:
|
|
39
|
+
from ..operators.grammar import StructuralPattern
|
|
40
|
+
|
|
41
|
+
from ..compat.dataclass import dataclass
|
|
42
|
+
from ..config.operator_names import (
|
|
43
|
+
COHERENCE,
|
|
44
|
+
CONTRACTION,
|
|
45
|
+
COUPLING,
|
|
46
|
+
DISSONANCE,
|
|
47
|
+
EMISSION,
|
|
48
|
+
EXPANSION,
|
|
49
|
+
MUTATION,
|
|
50
|
+
RECEPTION,
|
|
51
|
+
RECURSIVITY,
|
|
52
|
+
RESONANCE,
|
|
53
|
+
SELF_ORGANIZATION,
|
|
54
|
+
SILENCE,
|
|
55
|
+
TRANSITION,
|
|
56
|
+
)
|
|
57
|
+
from ..operators.health_analyzer import SequenceHealthAnalyzer
|
|
58
|
+
from ..operators.patterns import AdvancedPatternDetector
|
|
59
|
+
from ..validation.compatibility import (
|
|
60
|
+
GRADUATED_COMPATIBILITY,
|
|
61
|
+
CompatibilityLevel,
|
|
62
|
+
get_compatibility_level,
|
|
63
|
+
)
|
|
64
|
+
from .domain_templates import DOMAIN_TEMPLATES, get_template
|
|
65
|
+
|
|
66
|
+
__all__ = [
|
|
67
|
+
"ContextualSequenceGenerator",
|
|
68
|
+
"GenerationResult",
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# Operator groups for intelligent variation
|
|
73
|
+
_STABILIZERS = [COHERENCE, SELF_ORGANIZATION, SILENCE, RESONANCE]
|
|
74
|
+
_DESTABILIZERS = [DISSONANCE, MUTATION, EXPANSION]
|
|
75
|
+
_ACTIVATORS = [EMISSION, RECEPTION]
|
|
76
|
+
_CONNECTORS = [COUPLING, RESONANCE]
|
|
77
|
+
_TRANSFORMERS = [TRANSITION, RECURSIVITY, MUTATION]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@dataclass
|
|
81
|
+
class GenerationResult:
|
|
82
|
+
"""Result of a sequence generation operation.
|
|
83
|
+
|
|
84
|
+
Attributes
|
|
85
|
+
----------
|
|
86
|
+
sequence : list[str]
|
|
87
|
+
Generated operator sequence (canonical names).
|
|
88
|
+
health_score : float
|
|
89
|
+
Overall structural health score (0.0-1.0).
|
|
90
|
+
detected_pattern : str
|
|
91
|
+
Primary structural pattern detected.
|
|
92
|
+
domain : str | None
|
|
93
|
+
Domain context used for generation (if applicable).
|
|
94
|
+
objective : str | None
|
|
95
|
+
Specific objective within domain (if applicable).
|
|
96
|
+
method : str
|
|
97
|
+
Generation method used ("template", "pattern", "improvement").
|
|
98
|
+
recommendations : list[str]
|
|
99
|
+
Suggestions for further improvement.
|
|
100
|
+
metadata : dict[str, object]
|
|
101
|
+
Additional generation metadata.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
sequence: list[str]
|
|
105
|
+
health_score: float
|
|
106
|
+
detected_pattern: str
|
|
107
|
+
domain: str | None
|
|
108
|
+
objective: str | None
|
|
109
|
+
method: str
|
|
110
|
+
recommendations: list[str]
|
|
111
|
+
metadata: dict[str, object]
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class ContextualSequenceGenerator:
|
|
115
|
+
"""Generator for context-guided TNFR operator sequences.
|
|
116
|
+
|
|
117
|
+
This generator combines domain templates, pattern detection, and health
|
|
118
|
+
analysis to produce optimal operator sequences for specific contexts and
|
|
119
|
+
objectives. It supports:
|
|
120
|
+
|
|
121
|
+
- Domain/objective-based generation from curated templates
|
|
122
|
+
- Pattern-targeted generation to achieve specific structural patterns
|
|
123
|
+
- Sequence improvement with targeted recommendations
|
|
124
|
+
- Constraint-based filtering (health, length, pattern)
|
|
125
|
+
|
|
126
|
+
All generated sequences respect TNFR canonical principles:
|
|
127
|
+
- Operator closure (only canonical operators)
|
|
128
|
+
- Phase coherence (compatible transitions)
|
|
129
|
+
- Structural health (balanced forces)
|
|
130
|
+
- Operational fractality (composable patterns)
|
|
131
|
+
|
|
132
|
+
Examples
|
|
133
|
+
--------
|
|
134
|
+
>>> generator = ContextualSequenceGenerator()
|
|
135
|
+
>>> result = generator.generate_for_context(
|
|
136
|
+
... domain="therapeutic",
|
|
137
|
+
... objective="crisis_intervention"
|
|
138
|
+
... )
|
|
139
|
+
>>> print(result.sequence)
|
|
140
|
+
['emission', 'reception', 'coherence', 'resonance', 'silence']
|
|
141
|
+
>>> print(f"Health: {result.health_score:.2f}")
|
|
142
|
+
Health: 0.78
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
def __init__(self, seed: int | None = None) -> None:
|
|
146
|
+
"""Initialize the contextual sequence generator.
|
|
147
|
+
|
|
148
|
+
Parameters
|
|
149
|
+
----------
|
|
150
|
+
seed : int, optional
|
|
151
|
+
Random seed for deterministic generation. If None, generation
|
|
152
|
+
is non-deterministic.
|
|
153
|
+
"""
|
|
154
|
+
self.health_analyzer = SequenceHealthAnalyzer()
|
|
155
|
+
self.pattern_detector = AdvancedPatternDetector()
|
|
156
|
+
self._rng = random.Random(seed)
|
|
157
|
+
|
|
158
|
+
def generate_for_context(
|
|
159
|
+
self,
|
|
160
|
+
domain: str,
|
|
161
|
+
objective: str | None = None,
|
|
162
|
+
max_length: int = 10,
|
|
163
|
+
min_health: float = 0.70,
|
|
164
|
+
required_pattern: str | None = None,
|
|
165
|
+
) -> GenerationResult:
|
|
166
|
+
"""Generate optimal sequence for specific domain and objective.
|
|
167
|
+
|
|
168
|
+
This method uses domain templates as a starting point and applies
|
|
169
|
+
intelligent variations to meet constraints while maintaining structural
|
|
170
|
+
coherence.
|
|
171
|
+
|
|
172
|
+
Parameters
|
|
173
|
+
----------
|
|
174
|
+
domain : str
|
|
175
|
+
Application domain (therapeutic, educational, organizational, creative).
|
|
176
|
+
objective : str, optional
|
|
177
|
+
Specific objective within domain. If None, uses first template.
|
|
178
|
+
max_length : int, default=10
|
|
179
|
+
Maximum sequence length. Sequences longer than this will be trimmed.
|
|
180
|
+
min_health : float, default=0.70
|
|
181
|
+
Minimum required health score (0.0-1.0).
|
|
182
|
+
required_pattern : str, optional
|
|
183
|
+
If specified, generator will try to produce this pattern.
|
|
184
|
+
|
|
185
|
+
Returns
|
|
186
|
+
-------
|
|
187
|
+
GenerationResult
|
|
188
|
+
Complete generation result with sequence, health metrics, and metadata.
|
|
189
|
+
|
|
190
|
+
Raises
|
|
191
|
+
------
|
|
192
|
+
KeyError
|
|
193
|
+
If domain or objective not found.
|
|
194
|
+
ValueError
|
|
195
|
+
If no valid sequence can be generated meeting constraints.
|
|
196
|
+
|
|
197
|
+
Examples
|
|
198
|
+
--------
|
|
199
|
+
>>> generator = ContextualSequenceGenerator()
|
|
200
|
+
>>> result = generator.generate_for_context(
|
|
201
|
+
... domain="therapeutic",
|
|
202
|
+
... objective="crisis_intervention",
|
|
203
|
+
... min_health=0.75
|
|
204
|
+
... )
|
|
205
|
+
>>> print(result.sequence)
|
|
206
|
+
['emission', 'reception', 'coherence', 'resonance', 'silence']
|
|
207
|
+
"""
|
|
208
|
+
# Determine objective if not specified
|
|
209
|
+
if objective is None:
|
|
210
|
+
from .domain_templates import list_objectives
|
|
211
|
+
|
|
212
|
+
objectives = list_objectives(domain)
|
|
213
|
+
objective = objectives[0] if objectives else None
|
|
214
|
+
|
|
215
|
+
# Get base template
|
|
216
|
+
base_sequence = get_template(domain, objective)
|
|
217
|
+
|
|
218
|
+
# Apply length constraint
|
|
219
|
+
if len(base_sequence) > max_length:
|
|
220
|
+
base_sequence = self._trim_sequence(base_sequence, max_length)
|
|
221
|
+
|
|
222
|
+
# Analyze base template
|
|
223
|
+
health = self.health_analyzer.analyze_health(base_sequence)
|
|
224
|
+
|
|
225
|
+
# If template already meets requirements, return it
|
|
226
|
+
if health.overall_health >= min_health:
|
|
227
|
+
if required_pattern is None or self._matches_pattern(
|
|
228
|
+
base_sequence, required_pattern
|
|
229
|
+
):
|
|
230
|
+
return GenerationResult(
|
|
231
|
+
sequence=base_sequence,
|
|
232
|
+
health_score=health.overall_health,
|
|
233
|
+
detected_pattern=health.dominant_pattern,
|
|
234
|
+
domain=domain,
|
|
235
|
+
objective=objective,
|
|
236
|
+
method="template",
|
|
237
|
+
recommendations=health.recommendations,
|
|
238
|
+
metadata={
|
|
239
|
+
"template_used": True,
|
|
240
|
+
"variations_tried": 0,
|
|
241
|
+
},
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
# Generate variations to meet constraints
|
|
245
|
+
candidates = self._generate_variations(base_sequence, max_length, count=20)
|
|
246
|
+
|
|
247
|
+
# Filter candidates by constraints
|
|
248
|
+
valid_candidates = []
|
|
249
|
+
for candidate in candidates:
|
|
250
|
+
candidate_health = self.health_analyzer.analyze_health(candidate)
|
|
251
|
+
if candidate_health.overall_health >= min_health:
|
|
252
|
+
if required_pattern is None or self._matches_pattern(
|
|
253
|
+
candidate, required_pattern
|
|
254
|
+
):
|
|
255
|
+
valid_candidates.append((candidate, candidate_health))
|
|
256
|
+
|
|
257
|
+
if not valid_candidates:
|
|
258
|
+
# Fallback: return best candidate even if below threshold
|
|
259
|
+
all_with_health = [
|
|
260
|
+
(seq, self.health_analyzer.analyze_health(seq)) for seq in candidates
|
|
261
|
+
]
|
|
262
|
+
best_seq, best_health = max(
|
|
263
|
+
all_with_health, key=lambda x: x[1].overall_health
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
return GenerationResult(
|
|
267
|
+
sequence=best_seq,
|
|
268
|
+
health_score=best_health.overall_health,
|
|
269
|
+
detected_pattern=best_health.dominant_pattern,
|
|
270
|
+
domain=domain,
|
|
271
|
+
objective=objective,
|
|
272
|
+
method="template_variant",
|
|
273
|
+
recommendations=[
|
|
274
|
+
f"Warning: Could not meet min_health={min_health:.2f}",
|
|
275
|
+
f"Best achievable health: {best_health.overall_health:.2f}",
|
|
276
|
+
]
|
|
277
|
+
+ best_health.recommendations,
|
|
278
|
+
metadata={
|
|
279
|
+
"template_used": True,
|
|
280
|
+
"variations_tried": len(candidates),
|
|
281
|
+
"constraint_met": False,
|
|
282
|
+
},
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
# Select best valid candidate
|
|
286
|
+
best_seq, best_health = max(valid_candidates, key=lambda x: x[1].overall_health)
|
|
287
|
+
|
|
288
|
+
return GenerationResult(
|
|
289
|
+
sequence=best_seq,
|
|
290
|
+
health_score=best_health.overall_health,
|
|
291
|
+
detected_pattern=best_health.dominant_pattern,
|
|
292
|
+
domain=domain,
|
|
293
|
+
objective=objective,
|
|
294
|
+
method="template_optimized",
|
|
295
|
+
recommendations=best_health.recommendations,
|
|
296
|
+
metadata={
|
|
297
|
+
"template_used": True,
|
|
298
|
+
"variations_tried": len(candidates),
|
|
299
|
+
"valid_candidates": len(valid_candidates),
|
|
300
|
+
},
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
def generate_for_pattern(
|
|
304
|
+
self,
|
|
305
|
+
target_pattern: str,
|
|
306
|
+
max_length: int = 10,
|
|
307
|
+
min_health: float = 0.70,
|
|
308
|
+
) -> GenerationResult:
|
|
309
|
+
"""Generate sequence targeting a specific structural pattern.
|
|
310
|
+
|
|
311
|
+
Uses pattern signatures and characteristic operator combinations to
|
|
312
|
+
construct sequences that maximize the probability of matching the
|
|
313
|
+
target pattern while maintaining structural health.
|
|
314
|
+
|
|
315
|
+
Parameters
|
|
316
|
+
----------
|
|
317
|
+
target_pattern : str
|
|
318
|
+
Target structural pattern (e.g., "BOOTSTRAP", "THERAPEUTIC",
|
|
319
|
+
"STABILIZE").
|
|
320
|
+
max_length : int, default=10
|
|
321
|
+
Maximum sequence length.
|
|
322
|
+
min_health : float, default=0.70
|
|
323
|
+
Minimum required health score (0.0-1.0).
|
|
324
|
+
|
|
325
|
+
Returns
|
|
326
|
+
-------
|
|
327
|
+
GenerationResult
|
|
328
|
+
Complete generation result with sequence and metrics.
|
|
329
|
+
|
|
330
|
+
Raises
|
|
331
|
+
------
|
|
332
|
+
ValueError
|
|
333
|
+
If pattern name is not recognized or no valid sequence can be generated.
|
|
334
|
+
|
|
335
|
+
Examples
|
|
336
|
+
--------
|
|
337
|
+
>>> generator = ContextualSequenceGenerator()
|
|
338
|
+
>>> result = generator.generate_for_pattern("BOOTSTRAP", min_health=0.70)
|
|
339
|
+
>>> print(result.sequence)
|
|
340
|
+
['emission', 'coupling', 'coherence']
|
|
341
|
+
"""
|
|
342
|
+
# Get pattern signature
|
|
343
|
+
signature = self._get_pattern_signature(target_pattern)
|
|
344
|
+
|
|
345
|
+
# Build base sequence from signature
|
|
346
|
+
base_sequence = self._build_from_signature(signature, max_length)
|
|
347
|
+
|
|
348
|
+
# Analyze and optimize
|
|
349
|
+
health = self.health_analyzer.analyze_health(base_sequence)
|
|
350
|
+
|
|
351
|
+
if health.overall_health >= min_health:
|
|
352
|
+
return GenerationResult(
|
|
353
|
+
sequence=base_sequence,
|
|
354
|
+
health_score=health.overall_health,
|
|
355
|
+
detected_pattern=health.dominant_pattern,
|
|
356
|
+
domain=None,
|
|
357
|
+
objective=None,
|
|
358
|
+
method="pattern_direct",
|
|
359
|
+
recommendations=health.recommendations,
|
|
360
|
+
metadata={
|
|
361
|
+
"target_pattern": target_pattern,
|
|
362
|
+
"pattern_matched": self._matches_pattern(
|
|
363
|
+
base_sequence, target_pattern
|
|
364
|
+
),
|
|
365
|
+
},
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
# Generate variations to improve health
|
|
369
|
+
candidates = self._generate_variations(base_sequence, max_length, count=15)
|
|
370
|
+
|
|
371
|
+
# Filter by constraints and pattern match
|
|
372
|
+
valid_candidates = []
|
|
373
|
+
for candidate in candidates:
|
|
374
|
+
if self._matches_pattern(candidate, target_pattern):
|
|
375
|
+
candidate_health = self.health_analyzer.analyze_health(candidate)
|
|
376
|
+
if candidate_health.overall_health >= min_health:
|
|
377
|
+
valid_candidates.append((candidate, candidate_health))
|
|
378
|
+
|
|
379
|
+
if not valid_candidates:
|
|
380
|
+
# Return base even if below threshold
|
|
381
|
+
return GenerationResult(
|
|
382
|
+
sequence=base_sequence,
|
|
383
|
+
health_score=health.overall_health,
|
|
384
|
+
detected_pattern=health.dominant_pattern,
|
|
385
|
+
domain=None,
|
|
386
|
+
objective=None,
|
|
387
|
+
method="pattern_suboptimal",
|
|
388
|
+
recommendations=[
|
|
389
|
+
f"Warning: Could not meet min_health={min_health:.2f}",
|
|
390
|
+
f"Best achievable health: {health.overall_health:.2f}",
|
|
391
|
+
]
|
|
392
|
+
+ health.recommendations,
|
|
393
|
+
metadata={
|
|
394
|
+
"target_pattern": target_pattern,
|
|
395
|
+
"pattern_matched": self._matches_pattern(
|
|
396
|
+
base_sequence, target_pattern
|
|
397
|
+
),
|
|
398
|
+
"constraint_met": False,
|
|
399
|
+
},
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
# Select best valid candidate
|
|
403
|
+
best_seq, best_health = max(valid_candidates, key=lambda x: x[1].overall_health)
|
|
404
|
+
|
|
405
|
+
return GenerationResult(
|
|
406
|
+
sequence=best_seq,
|
|
407
|
+
health_score=best_health.overall_health,
|
|
408
|
+
detected_pattern=best_health.dominant_pattern,
|
|
409
|
+
domain=None,
|
|
410
|
+
objective=None,
|
|
411
|
+
method="pattern_optimized",
|
|
412
|
+
recommendations=best_health.recommendations,
|
|
413
|
+
metadata={
|
|
414
|
+
"target_pattern": target_pattern,
|
|
415
|
+
"pattern_matched": True,
|
|
416
|
+
"variations_tried": len(candidates),
|
|
417
|
+
},
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
def improve_sequence(
|
|
421
|
+
self,
|
|
422
|
+
current: list[str],
|
|
423
|
+
target_health: float | None = None,
|
|
424
|
+
max_length: int | None = None,
|
|
425
|
+
) -> tuple[list[str], list[str]]:
|
|
426
|
+
"""Improve existing sequence with targeted recommendations.
|
|
427
|
+
|
|
428
|
+
Analyzes the current sequence, identifies weaknesses, and generates
|
|
429
|
+
an improved version along with specific recommendations explaining
|
|
430
|
+
the improvements made.
|
|
431
|
+
|
|
432
|
+
Parameters
|
|
433
|
+
----------
|
|
434
|
+
current : list[str]
|
|
435
|
+
Current operator sequence to improve.
|
|
436
|
+
target_health : float, optional
|
|
437
|
+
Target health score. If None, aims for current + 0.15.
|
|
438
|
+
max_length : int, optional
|
|
439
|
+
Maximum allowed length for improved sequence. If None, allows
|
|
440
|
+
length to increase by up to 3 operators.
|
|
441
|
+
|
|
442
|
+
Returns
|
|
443
|
+
-------
|
|
444
|
+
tuple[list[str], list[str]]
|
|
445
|
+
A tuple containing:
|
|
446
|
+
- Improved operator sequence
|
|
447
|
+
- List of recommendations explaining improvements
|
|
448
|
+
|
|
449
|
+
Examples
|
|
450
|
+
--------
|
|
451
|
+
>>> generator = ContextualSequenceGenerator()
|
|
452
|
+
>>> current = ["emission", "coherence", "silence"]
|
|
453
|
+
>>> improved, recommendations = generator.improve_sequence(current)
|
|
454
|
+
>>> print(improved)
|
|
455
|
+
['emission', 'reception', 'coherence', 'resonance', 'silence']
|
|
456
|
+
>>> print(recommendations[0])
|
|
457
|
+
'Added reception after emission: improves completeness (+0.25)'
|
|
458
|
+
"""
|
|
459
|
+
# Analyze current sequence
|
|
460
|
+
current_health = self.health_analyzer.analyze_health(current)
|
|
461
|
+
|
|
462
|
+
# Set target health
|
|
463
|
+
if target_health is None:
|
|
464
|
+
target_health = min(1.0, current_health.overall_health + 0.15)
|
|
465
|
+
|
|
466
|
+
# Set max length
|
|
467
|
+
if max_length is None:
|
|
468
|
+
max_length = len(current) + 3
|
|
469
|
+
|
|
470
|
+
# Generate improvement candidates
|
|
471
|
+
improvements = self._generate_improvements(
|
|
472
|
+
current, current_health, target_health, max_length
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
# Select best improvement
|
|
476
|
+
best_improvement = max(
|
|
477
|
+
improvements,
|
|
478
|
+
key=lambda seq: self.health_analyzer.analyze_health(seq).overall_health,
|
|
479
|
+
)
|
|
480
|
+
|
|
481
|
+
# Generate explanatory recommendations
|
|
482
|
+
recommendations = self._explain_improvements(current, best_improvement)
|
|
483
|
+
|
|
484
|
+
return best_improvement, recommendations
|
|
485
|
+
|
|
486
|
+
# =========================================================================
|
|
487
|
+
# INTERNAL HELPER METHODS
|
|
488
|
+
# =========================================================================
|
|
489
|
+
|
|
490
|
+
def _trim_sequence(self, sequence: list[str], max_length: int) -> list[str]:
|
|
491
|
+
"""Trim sequence to max_length while preserving structure."""
|
|
492
|
+
if len(sequence) <= max_length:
|
|
493
|
+
return sequence
|
|
494
|
+
|
|
495
|
+
# Try to preserve ending if it's a stabilizer
|
|
496
|
+
if sequence[-1] in _STABILIZERS:
|
|
497
|
+
# Keep ending, trim from middle
|
|
498
|
+
keep_start = max_length // 2
|
|
499
|
+
keep_end = max_length - keep_start
|
|
500
|
+
return sequence[:keep_start] + sequence[-keep_end:]
|
|
501
|
+
else:
|
|
502
|
+
# Simple truncation
|
|
503
|
+
return sequence[:max_length]
|
|
504
|
+
|
|
505
|
+
def _generate_variations(
|
|
506
|
+
self, base: list[str], max_length: int, count: int = 20
|
|
507
|
+
) -> list[list[str]]:
|
|
508
|
+
"""Generate variations of a base sequence."""
|
|
509
|
+
variations = [base]
|
|
510
|
+
|
|
511
|
+
for _ in range(count):
|
|
512
|
+
variation = base.copy()
|
|
513
|
+
|
|
514
|
+
# Random modification
|
|
515
|
+
modification = self._rng.choice(["insert", "remove", "replace", "extend"])
|
|
516
|
+
|
|
517
|
+
if modification == "insert" and len(variation) < max_length:
|
|
518
|
+
pos = self._rng.randint(0, len(variation))
|
|
519
|
+
new_op = self._select_compatible_operator(
|
|
520
|
+
variation[pos - 1] if pos > 0 else None,
|
|
521
|
+
variation[pos] if pos < len(variation) else None,
|
|
522
|
+
)
|
|
523
|
+
if new_op:
|
|
524
|
+
variation.insert(pos, new_op)
|
|
525
|
+
|
|
526
|
+
elif modification == "remove" and len(variation) > 3:
|
|
527
|
+
pos = self._rng.randint(0, len(variation) - 1)
|
|
528
|
+
# Don't remove if it breaks compatibility
|
|
529
|
+
if self._can_remove(variation, pos):
|
|
530
|
+
variation.pop(pos)
|
|
531
|
+
|
|
532
|
+
elif modification == "replace":
|
|
533
|
+
pos = self._rng.randint(0, len(variation) - 1)
|
|
534
|
+
new_op = self._select_compatible_operator(
|
|
535
|
+
variation[pos - 1] if pos > 0 else None,
|
|
536
|
+
variation[pos + 1] if pos < len(variation) - 1 else None,
|
|
537
|
+
)
|
|
538
|
+
if new_op:
|
|
539
|
+
variation[pos] = new_op
|
|
540
|
+
|
|
541
|
+
elif modification == "extend" and len(variation) < max_length:
|
|
542
|
+
new_op = self._select_compatible_operator(variation[-1], None)
|
|
543
|
+
if new_op:
|
|
544
|
+
variation.append(new_op)
|
|
545
|
+
|
|
546
|
+
variations.append(variation)
|
|
547
|
+
|
|
548
|
+
return variations
|
|
549
|
+
|
|
550
|
+
def _select_compatible_operator(
|
|
551
|
+
self, prev: str | None, next_op: str | None
|
|
552
|
+
) -> str | None:
|
|
553
|
+
"""Select an operator compatible with neighbors."""
|
|
554
|
+
all_operators = [
|
|
555
|
+
EMISSION,
|
|
556
|
+
RECEPTION,
|
|
557
|
+
COHERENCE,
|
|
558
|
+
DISSONANCE,
|
|
559
|
+
COUPLING,
|
|
560
|
+
RESONANCE,
|
|
561
|
+
SILENCE,
|
|
562
|
+
EXPANSION,
|
|
563
|
+
CONTRACTION,
|
|
564
|
+
SELF_ORGANIZATION,
|
|
565
|
+
MUTATION,
|
|
566
|
+
TRANSITION,
|
|
567
|
+
RECURSIVITY,
|
|
568
|
+
]
|
|
569
|
+
|
|
570
|
+
if prev is None and next_op is None:
|
|
571
|
+
return self._rng.choice(all_operators)
|
|
572
|
+
|
|
573
|
+
compatible = []
|
|
574
|
+
|
|
575
|
+
if prev is not None and next_op is None:
|
|
576
|
+
# Find operators compatible after prev
|
|
577
|
+
if prev in GRADUATED_COMPATIBILITY:
|
|
578
|
+
levels = GRADUATED_COMPATIBILITY[prev]
|
|
579
|
+
compatible.extend(levels.get("excellent", []))
|
|
580
|
+
compatible.extend(levels.get("good", []))
|
|
581
|
+
|
|
582
|
+
elif prev is None and next_op is not None:
|
|
583
|
+
# Find operators that can precede next_op
|
|
584
|
+
for op in all_operators:
|
|
585
|
+
level = get_compatibility_level(op, next_op)
|
|
586
|
+
if level in (CompatibilityLevel.EXCELLENT, CompatibilityLevel.GOOD):
|
|
587
|
+
compatible.append(op)
|
|
588
|
+
|
|
589
|
+
else:
|
|
590
|
+
# Must be compatible with both
|
|
591
|
+
for op in all_operators:
|
|
592
|
+
if prev and next_op:
|
|
593
|
+
level_after = get_compatibility_level(prev, op)
|
|
594
|
+
level_before = get_compatibility_level(op, next_op)
|
|
595
|
+
if level_after in (
|
|
596
|
+
CompatibilityLevel.EXCELLENT,
|
|
597
|
+
CompatibilityLevel.GOOD,
|
|
598
|
+
) and level_before in (
|
|
599
|
+
CompatibilityLevel.EXCELLENT,
|
|
600
|
+
CompatibilityLevel.GOOD,
|
|
601
|
+
):
|
|
602
|
+
compatible.append(op)
|
|
603
|
+
|
|
604
|
+
return self._rng.choice(compatible) if compatible else None
|
|
605
|
+
|
|
606
|
+
def _can_remove(self, sequence: list[str], pos: int) -> bool:
|
|
607
|
+
"""Check if operator at pos can be safely removed."""
|
|
608
|
+
if pos == 0 or pos == len(sequence) - 1:
|
|
609
|
+
return True # Can always remove endpoints
|
|
610
|
+
|
|
611
|
+
prev = sequence[pos - 1]
|
|
612
|
+
next_op = sequence[pos + 1]
|
|
613
|
+
|
|
614
|
+
level = get_compatibility_level(prev, next_op)
|
|
615
|
+
return level in (CompatibilityLevel.EXCELLENT, CompatibilityLevel.GOOD)
|
|
616
|
+
|
|
617
|
+
def _matches_pattern(self, sequence: list[str], pattern_name: str) -> bool:
|
|
618
|
+
"""Check if sequence matches the specified pattern."""
|
|
619
|
+
detected = self.pattern_detector.detect_pattern(sequence)
|
|
620
|
+
return detected.value == pattern_name
|
|
621
|
+
|
|
622
|
+
def _get_pattern_signature(self, pattern_name: str) -> dict[str, list[str]]:
|
|
623
|
+
"""Get characteristic signature for a structural pattern."""
|
|
624
|
+
# Pattern signatures mapping pattern names to operator combinations
|
|
625
|
+
signatures: dict[str, dict[str, list[str]]] = {
|
|
626
|
+
"BOOTSTRAP": {
|
|
627
|
+
"core": [EMISSION, COUPLING, COHERENCE],
|
|
628
|
+
"optional": [RECEPTION, SILENCE],
|
|
629
|
+
"avoid": [DISSONANCE, MUTATION],
|
|
630
|
+
},
|
|
631
|
+
"THERAPEUTIC": {
|
|
632
|
+
"core": [
|
|
633
|
+
EMISSION,
|
|
634
|
+
RECEPTION,
|
|
635
|
+
COHERENCE,
|
|
636
|
+
DISSONANCE,
|
|
637
|
+
SELF_ORGANIZATION,
|
|
638
|
+
COHERENCE,
|
|
639
|
+
],
|
|
640
|
+
"optional": [SILENCE, TRANSITION],
|
|
641
|
+
"avoid": [],
|
|
642
|
+
},
|
|
643
|
+
"EDUCATIONAL": {
|
|
644
|
+
"core": [RECEPTION, COHERENCE, EXPANSION, DISSONANCE, MUTATION],
|
|
645
|
+
"optional": [EMISSION, COHERENCE, SILENCE],
|
|
646
|
+
"avoid": [],
|
|
647
|
+
},
|
|
648
|
+
"ORGANIZATIONAL": {
|
|
649
|
+
"core": [
|
|
650
|
+
TRANSITION,
|
|
651
|
+
EMISSION,
|
|
652
|
+
RECEPTION,
|
|
653
|
+
COUPLING,
|
|
654
|
+
DISSONANCE,
|
|
655
|
+
SELF_ORGANIZATION,
|
|
656
|
+
],
|
|
657
|
+
"optional": [COHERENCE, RESONANCE],
|
|
658
|
+
"avoid": [],
|
|
659
|
+
},
|
|
660
|
+
"CREATIVE": {
|
|
661
|
+
"core": [
|
|
662
|
+
SILENCE,
|
|
663
|
+
EMISSION,
|
|
664
|
+
EXPANSION,
|
|
665
|
+
DISSONANCE,
|
|
666
|
+
MUTATION,
|
|
667
|
+
SELF_ORGANIZATION,
|
|
668
|
+
],
|
|
669
|
+
"optional": [COHERENCE, RECURSIVITY],
|
|
670
|
+
"avoid": [],
|
|
671
|
+
},
|
|
672
|
+
"STABILIZE": {
|
|
673
|
+
"core": [COHERENCE, SILENCE],
|
|
674
|
+
"optional": [RESONANCE, COHERENCE],
|
|
675
|
+
"avoid": [DISSONANCE, MUTATION, EXPANSION],
|
|
676
|
+
},
|
|
677
|
+
"EXPLORE": {
|
|
678
|
+
"core": [DISSONANCE, MUTATION, COHERENCE],
|
|
679
|
+
"optional": [EMISSION, RECEPTION],
|
|
680
|
+
"avoid": [SILENCE],
|
|
681
|
+
},
|
|
682
|
+
"RESONATE": {
|
|
683
|
+
"core": [RESONANCE, COUPLING, RESONANCE],
|
|
684
|
+
"optional": [COHERENCE, EMISSION],
|
|
685
|
+
"avoid": [DISSONANCE, MUTATION],
|
|
686
|
+
},
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
if pattern_name not in signatures:
|
|
690
|
+
# Default signature for unknown patterns
|
|
691
|
+
return {
|
|
692
|
+
"core": [EMISSION, COHERENCE, SILENCE],
|
|
693
|
+
"optional": [RECEPTION, RESONANCE],
|
|
694
|
+
"avoid": [],
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
return signatures[pattern_name]
|
|
698
|
+
|
|
699
|
+
def _build_from_signature(
|
|
700
|
+
self, signature: dict[str, list[str]], max_length: int
|
|
701
|
+
) -> list[str]:
|
|
702
|
+
"""Build sequence from pattern signature."""
|
|
703
|
+
core = signature["core"]
|
|
704
|
+
optional = signature.get("optional", [])
|
|
705
|
+
|
|
706
|
+
# Start with core
|
|
707
|
+
sequence = list(core)
|
|
708
|
+
|
|
709
|
+
# Add optional operators if room and improves health
|
|
710
|
+
remaining = max_length - len(sequence)
|
|
711
|
+
if remaining > 0 and optional:
|
|
712
|
+
for op in optional:
|
|
713
|
+
if len(sequence) < max_length:
|
|
714
|
+
# Try to insert at compatible position
|
|
715
|
+
for i in range(len(sequence) + 1):
|
|
716
|
+
prev = sequence[i - 1] if i > 0 else None
|
|
717
|
+
next_op = sequence[i] if i < len(sequence) else None
|
|
718
|
+
|
|
719
|
+
if prev is None or get_compatibility_level(prev, op) in (
|
|
720
|
+
CompatibilityLevel.EXCELLENT,
|
|
721
|
+
CompatibilityLevel.GOOD,
|
|
722
|
+
):
|
|
723
|
+
if next_op is None or get_compatibility_level(
|
|
724
|
+
op, next_op
|
|
725
|
+
) in (
|
|
726
|
+
CompatibilityLevel.EXCELLENT,
|
|
727
|
+
CompatibilityLevel.GOOD,
|
|
728
|
+
):
|
|
729
|
+
sequence.insert(i, op)
|
|
730
|
+
break
|
|
731
|
+
|
|
732
|
+
return sequence[:max_length]
|
|
733
|
+
|
|
734
|
+
def _generate_improvements(
|
|
735
|
+
self,
|
|
736
|
+
current: list[str],
|
|
737
|
+
current_health: object,
|
|
738
|
+
target_health: float,
|
|
739
|
+
max_length: int,
|
|
740
|
+
) -> list[list[str]]:
|
|
741
|
+
"""Generate candidate improvements for a sequence."""
|
|
742
|
+
improvements = [current]
|
|
743
|
+
|
|
744
|
+
# Strategy 1: Add missing phases
|
|
745
|
+
if hasattr(current_health, "pattern_completeness"):
|
|
746
|
+
if current_health.pattern_completeness < 0.75: # type: ignore[attr-defined]
|
|
747
|
+
# Try adding activation
|
|
748
|
+
if not any(op in [EMISSION, RECEPTION] for op in current):
|
|
749
|
+
for pos in range(min(2, len(current))):
|
|
750
|
+
candidate = current.copy()
|
|
751
|
+
candidate.insert(pos, RECEPTION)
|
|
752
|
+
if len(candidate) <= max_length:
|
|
753
|
+
improvements.append(candidate)
|
|
754
|
+
|
|
755
|
+
# Strategy 2: Add stabilizers if unbalanced
|
|
756
|
+
if hasattr(current_health, "balance_score"):
|
|
757
|
+
if current_health.balance_score < 0.6: # type: ignore[attr-defined]
|
|
758
|
+
for stabilizer in _STABILIZERS:
|
|
759
|
+
candidate = current.copy()
|
|
760
|
+
if len(candidate) < max_length:
|
|
761
|
+
candidate.append(stabilizer)
|
|
762
|
+
improvements.append(candidate)
|
|
763
|
+
|
|
764
|
+
# Strategy 3: Improve ending
|
|
765
|
+
if hasattr(current_health, "sustainability_index"):
|
|
766
|
+
if (
|
|
767
|
+
current_health.sustainability_index < 0.7 # type: ignore[attr-defined]
|
|
768
|
+
and current[-1] not in _STABILIZERS
|
|
769
|
+
):
|
|
770
|
+
for stabilizer in _STABILIZERS:
|
|
771
|
+
candidate = current.copy()
|
|
772
|
+
candidate.append(stabilizer)
|
|
773
|
+
if len(candidate) <= max_length:
|
|
774
|
+
improvements.append(candidate)
|
|
775
|
+
|
|
776
|
+
# Strategy 4: Add resonance for amplification
|
|
777
|
+
if RESONANCE not in current and len(current) < max_length:
|
|
778
|
+
for i in range(1, len(current)):
|
|
779
|
+
if current[i - 1] in [COUPLING, COHERENCE, EXPANSION]:
|
|
780
|
+
candidate = current.copy()
|
|
781
|
+
candidate.insert(i, RESONANCE)
|
|
782
|
+
if len(candidate) <= max_length:
|
|
783
|
+
improvements.append(candidate)
|
|
784
|
+
|
|
785
|
+
return improvements
|
|
786
|
+
|
|
787
|
+
def _explain_improvements(
|
|
788
|
+
self, original: list[str], improved: list[str]
|
|
789
|
+
) -> list[str]:
|
|
790
|
+
"""Generate explanations for improvements made."""
|
|
791
|
+
recommendations = []
|
|
792
|
+
|
|
793
|
+
# Analyze differences
|
|
794
|
+
original_health = self.health_analyzer.analyze_health(original)
|
|
795
|
+
improved_health = self.health_analyzer.analyze_health(improved)
|
|
796
|
+
|
|
797
|
+
# Overall improvement
|
|
798
|
+
health_delta = improved_health.overall_health - original_health.overall_health
|
|
799
|
+
if health_delta > 0.01:
|
|
800
|
+
recommendations.append(
|
|
801
|
+
f"Overall health improved by {health_delta:.2f} "
|
|
802
|
+
f"(from {original_health.overall_health:.2f} to {improved_health.overall_health:.2f})"
|
|
803
|
+
)
|
|
804
|
+
|
|
805
|
+
# Specific metric improvements
|
|
806
|
+
if improved_health.coherence_index > original_health.coherence_index + 0.05:
|
|
807
|
+
recommendations.append(
|
|
808
|
+
f"Coherence improved by {improved_health.coherence_index - original_health.coherence_index:.2f}"
|
|
809
|
+
)
|
|
810
|
+
|
|
811
|
+
if improved_health.balance_score > original_health.balance_score + 0.05:
|
|
812
|
+
recommendations.append(
|
|
813
|
+
f"Balance improved by {improved_health.balance_score - original_health.balance_score:.2f}"
|
|
814
|
+
)
|
|
815
|
+
|
|
816
|
+
if (
|
|
817
|
+
improved_health.sustainability_index
|
|
818
|
+
> original_health.sustainability_index + 0.05
|
|
819
|
+
):
|
|
820
|
+
recommendations.append(
|
|
821
|
+
f"Sustainability improved by {improved_health.sustainability_index - original_health.sustainability_index:.2f}"
|
|
822
|
+
)
|
|
823
|
+
|
|
824
|
+
# Identify added operators
|
|
825
|
+
from collections import Counter
|
|
826
|
+
|
|
827
|
+
original_counts = Counter(original)
|
|
828
|
+
improved_counts = Counter(improved)
|
|
829
|
+
added = [
|
|
830
|
+
op
|
|
831
|
+
for op in improved_counts
|
|
832
|
+
if improved_counts[op] > original_counts.get(op, 0)
|
|
833
|
+
]
|
|
834
|
+
if added:
|
|
835
|
+
recommendations.append(f"Added operators: {', '.join(set(added))}")
|
|
836
|
+
|
|
837
|
+
# Pattern change
|
|
838
|
+
if improved_health.dominant_pattern != original_health.dominant_pattern:
|
|
839
|
+
recommendations.append(
|
|
840
|
+
f"Pattern evolved from {original_health.dominant_pattern} to {improved_health.dominant_pattern}"
|
|
841
|
+
)
|
|
842
|
+
|
|
843
|
+
if not recommendations:
|
|
844
|
+
recommendations.append("Sequence maintained with minor refinements")
|
|
845
|
+
|
|
846
|
+
return recommendations
|