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/cli/execution.pyi
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
|
|
7
|
+
import networkx as nx
|
|
8
|
+
|
|
9
|
+
from ..config import apply_config
|
|
10
|
+
from ..config.presets import get_preset
|
|
11
|
+
from ..constants import METRIC_DEFAULTS
|
|
12
|
+
from ..dynamics import (
|
|
13
|
+
default_glyph_selector,
|
|
14
|
+
parametric_glyph_selector,
|
|
15
|
+
run,
|
|
16
|
+
validate_canon,
|
|
17
|
+
)
|
|
18
|
+
from ..execution import CANONICAL_PRESET_NAME, play, seq
|
|
19
|
+
from ..flatten import parse_program_tokens
|
|
20
|
+
from ..glyph_history import ensure_history
|
|
21
|
+
from ..metrics import (
|
|
22
|
+
build_metrics_summary,
|
|
23
|
+
export_metrics,
|
|
24
|
+
glyph_top,
|
|
25
|
+
register_metrics_callbacks,
|
|
26
|
+
)
|
|
27
|
+
from ..metrics.core import _metrics_step
|
|
28
|
+
from ..ontosim import prepare_network
|
|
29
|
+
from ..sense import register_sigma_callback
|
|
30
|
+
from ..trace import register_trace
|
|
31
|
+
from ..types import Glyph, ProgramTokens
|
|
32
|
+
from ..utils import (
|
|
33
|
+
StructuredFileError,
|
|
34
|
+
get_logger,
|
|
35
|
+
json_dumps,
|
|
36
|
+
read_structured_file,
|
|
37
|
+
safe_write,
|
|
38
|
+
)
|
|
39
|
+
from .arguments import _args_to_dict
|
|
40
|
+
|
|
41
|
+
DEFAULT_SUMMARY_SERIES_LIMIT: int
|
|
42
|
+
logger: Any
|
|
43
|
+
|
|
44
|
+
def _save_json(path: str, data: Any) -> None: ...
|
|
45
|
+
def _attach_callbacks(G: nx.Graph) -> None: ...
|
|
46
|
+
def _persist_history(G: nx.Graph, args: argparse.Namespace) -> None: ...
|
|
47
|
+
def build_basic_graph(args: argparse.Namespace) -> nx.Graph: ...
|
|
48
|
+
def apply_cli_config(G: nx.Graph, args: argparse.Namespace) -> None: ...
|
|
49
|
+
def register_callbacks_and_observer(G: nx.Graph) -> None: ...
|
|
50
|
+
def _build_graph_from_args(args: argparse.Namespace) -> nx.Graph: ...
|
|
51
|
+
def _load_sequence(path: Path) -> ProgramTokens: ...
|
|
52
|
+
def resolve_program(
|
|
53
|
+
args: argparse.Namespace, default: Optional[ProgramTokens] = ...
|
|
54
|
+
) -> Optional[ProgramTokens]: ...
|
|
55
|
+
def run_program(
|
|
56
|
+
G: Optional[nx.Graph],
|
|
57
|
+
program: Optional[ProgramTokens],
|
|
58
|
+
args: argparse.Namespace,
|
|
59
|
+
) -> nx.Graph: ...
|
|
60
|
+
def _run_cli_program(
|
|
61
|
+
args: argparse.Namespace,
|
|
62
|
+
*,
|
|
63
|
+
default_program: Optional[ProgramTokens] = ...,
|
|
64
|
+
graph: Optional[nx.Graph] = ...,
|
|
65
|
+
) -> tuple[int, Optional[nx.Graph]]: ...
|
|
66
|
+
def _log_run_summaries(G: nx.Graph, args: argparse.Namespace) -> None: ...
|
|
67
|
+
def cmd_run(args: argparse.Namespace) -> int: ...
|
|
68
|
+
def cmd_sequence(args: argparse.Namespace) -> int: ...
|
|
69
|
+
def cmd_metrics(args: argparse.Namespace) -> int: ...
|
|
70
|
+
def cmd_profile_si(args: argparse.Namespace) -> int: ...
|
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Interactive CLI validator for TNFR operator sequences.
|
|
3
|
+
|
|
4
|
+
Provides a user-friendly terminal interface for validating, analyzing,
|
|
5
|
+
optimizing, and exploring TNFR operator sequences without requiring
|
|
6
|
+
programming knowledge.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import sys
|
|
12
|
+
from typing import TYPE_CHECKING, Optional
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from ..operators.grammar import SequenceValidationResult
|
|
16
|
+
from ..operators.health_analyzer import SequenceHealthMetrics
|
|
17
|
+
from ..tools.sequence_generator import GenerationResult
|
|
18
|
+
|
|
19
|
+
from ..operators.grammar import validate_sequence_with_health
|
|
20
|
+
from ..operators.health_analyzer import SequenceHealthAnalyzer
|
|
21
|
+
from ..tools.sequence_generator import ContextualSequenceGenerator
|
|
22
|
+
from ..tools.domain_templates import list_domains, list_objectives
|
|
23
|
+
|
|
24
|
+
__all__ = ["TNFRInteractiveValidator", "run_interactive_validator"]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class TNFRInteractiveValidator:
|
|
28
|
+
"""Interactive validator for TNFR operator sequences.
|
|
29
|
+
|
|
30
|
+
Provides a conversational interface for users to validate, generate,
|
|
31
|
+
optimize, and explore TNFR operator sequences with real-time feedback
|
|
32
|
+
and visual health metrics.
|
|
33
|
+
|
|
34
|
+
Examples
|
|
35
|
+
--------
|
|
36
|
+
>>> validator = TNFRInteractiveValidator()
|
|
37
|
+
>>> validator.run_interactive_session()
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(self, seed: Optional[int] = None):
|
|
41
|
+
"""Initialize the interactive validator.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
seed : int, optional
|
|
46
|
+
Random seed for deterministic sequence generation.
|
|
47
|
+
"""
|
|
48
|
+
self.generator = ContextualSequenceGenerator(seed=seed)
|
|
49
|
+
self.analyzer = SequenceHealthAnalyzer()
|
|
50
|
+
self.running = True
|
|
51
|
+
|
|
52
|
+
def run_interactive_session(self) -> None:
|
|
53
|
+
"""Run the main interactive session with menu navigation."""
|
|
54
|
+
self._show_welcome()
|
|
55
|
+
|
|
56
|
+
while self.running:
|
|
57
|
+
try:
|
|
58
|
+
choice = self._show_main_menu()
|
|
59
|
+
|
|
60
|
+
if choice == "v":
|
|
61
|
+
self._interactive_validate()
|
|
62
|
+
elif choice == "g":
|
|
63
|
+
self._interactive_generate()
|
|
64
|
+
elif choice == "o":
|
|
65
|
+
self._interactive_optimize()
|
|
66
|
+
elif choice == "e":
|
|
67
|
+
self._interactive_explore()
|
|
68
|
+
elif choice == "h":
|
|
69
|
+
self._show_help()
|
|
70
|
+
elif choice == "q":
|
|
71
|
+
self.running = False
|
|
72
|
+
print("\nThank you for using TNFR Interactive Validator!")
|
|
73
|
+
else:
|
|
74
|
+
print(f"\n⚠ Invalid choice: '{choice}'. Please try again.\n")
|
|
75
|
+
|
|
76
|
+
except KeyboardInterrupt:
|
|
77
|
+
print("\n\n⚠ Interrupted. Returning to main menu...\n")
|
|
78
|
+
except EOFError:
|
|
79
|
+
print("\n\nGoodbye!")
|
|
80
|
+
self.running = False
|
|
81
|
+
|
|
82
|
+
def _show_welcome(self) -> None:
|
|
83
|
+
"""Display welcome banner."""
|
|
84
|
+
print()
|
|
85
|
+
print("┌" + "─" * 58 + "┐")
|
|
86
|
+
print("│" + " " * 10 + "TNFR Interactive Sequence Validator" + " " * 13 + "│")
|
|
87
|
+
print("│" + " " * 15 + "Grammar 2.0 - Full Capabilities" + " " * 12 + "│")
|
|
88
|
+
print("└" + "─" * 58 + "┘")
|
|
89
|
+
print()
|
|
90
|
+
|
|
91
|
+
def _show_main_menu(self) -> str:
|
|
92
|
+
"""Show main menu and get user choice.
|
|
93
|
+
|
|
94
|
+
Returns
|
|
95
|
+
-------
|
|
96
|
+
str
|
|
97
|
+
User's menu choice.
|
|
98
|
+
"""
|
|
99
|
+
print("Main Menu:")
|
|
100
|
+
print(" [v] Validate a sequence")
|
|
101
|
+
print(" [g] Generate new sequence")
|
|
102
|
+
print(" [o] Optimize existing sequence")
|
|
103
|
+
print(" [e] Explore patterns and domains")
|
|
104
|
+
print(" [h] Help and documentation")
|
|
105
|
+
print(" [q] Quit")
|
|
106
|
+
print()
|
|
107
|
+
|
|
108
|
+
choice = input("Select option: ").strip().lower()
|
|
109
|
+
return choice
|
|
110
|
+
|
|
111
|
+
def _interactive_validate(self) -> None:
|
|
112
|
+
"""Interactive sequence validation with visual feedback."""
|
|
113
|
+
print("\n" + "─" * 60)
|
|
114
|
+
print("VALIDATE SEQUENCE")
|
|
115
|
+
print("─" * 60)
|
|
116
|
+
print("Enter operators separated by spaces or commas.")
|
|
117
|
+
print("Example: emission reception coherence silence")
|
|
118
|
+
print()
|
|
119
|
+
|
|
120
|
+
sequence_input = input("Sequence: ").strip()
|
|
121
|
+
if not sequence_input:
|
|
122
|
+
print("⚠ Empty sequence. Returning to menu.\n")
|
|
123
|
+
return
|
|
124
|
+
|
|
125
|
+
# Parse sequence (handle both space and comma separation)
|
|
126
|
+
sequence = self._parse_sequence_input(sequence_input)
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
result = validate_sequence_with_health(sequence)
|
|
130
|
+
|
|
131
|
+
if result.passed:
|
|
132
|
+
self._display_success(result, sequence)
|
|
133
|
+
|
|
134
|
+
# Suggest improvements if health is moderate
|
|
135
|
+
if result.health_metrics and result.health_metrics.overall_health < 0.8:
|
|
136
|
+
self._suggest_improvements(sequence, result.health_metrics)
|
|
137
|
+
else:
|
|
138
|
+
self._display_error(result)
|
|
139
|
+
self._suggest_fixes(sequence, result.error)
|
|
140
|
+
|
|
141
|
+
except Exception as e:
|
|
142
|
+
self._display_exception(e)
|
|
143
|
+
|
|
144
|
+
print()
|
|
145
|
+
|
|
146
|
+
def _interactive_generate(self) -> None:
|
|
147
|
+
"""Interactive sequence generation with guided menus."""
|
|
148
|
+
print("\n" + "─" * 60)
|
|
149
|
+
print("GENERATE SEQUENCE")
|
|
150
|
+
print("─" * 60)
|
|
151
|
+
print()
|
|
152
|
+
|
|
153
|
+
# Ask generation mode
|
|
154
|
+
print("Generation mode:")
|
|
155
|
+
print(" [d] By domain and objective")
|
|
156
|
+
print(" [p] By structural pattern")
|
|
157
|
+
print(" [b] Back to main menu")
|
|
158
|
+
print()
|
|
159
|
+
|
|
160
|
+
mode = input("Select mode: ").strip().lower()
|
|
161
|
+
|
|
162
|
+
if mode == "b":
|
|
163
|
+
return
|
|
164
|
+
elif mode == "d":
|
|
165
|
+
self._generate_by_domain()
|
|
166
|
+
elif mode == "p":
|
|
167
|
+
self._generate_by_pattern()
|
|
168
|
+
else:
|
|
169
|
+
print(f"⚠ Invalid mode: '{mode}'\n")
|
|
170
|
+
|
|
171
|
+
def _generate_by_domain(self) -> None:
|
|
172
|
+
"""Generate sequence by selecting domain and objective."""
|
|
173
|
+
# Select domain
|
|
174
|
+
domains = list_domains()
|
|
175
|
+
print("\nAvailable domains:")
|
|
176
|
+
for i, domain in enumerate(domains, 1):
|
|
177
|
+
print(f" {i}. {domain}")
|
|
178
|
+
print()
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
domain_idx = int(input("Select domain (number): ").strip()) - 1
|
|
182
|
+
if domain_idx < 0 or domain_idx >= len(domains):
|
|
183
|
+
print("⚠ Invalid selection.\n")
|
|
184
|
+
return
|
|
185
|
+
domain = domains[domain_idx]
|
|
186
|
+
except (ValueError, EOFError):
|
|
187
|
+
print("⚠ Invalid input.\n")
|
|
188
|
+
return
|
|
189
|
+
|
|
190
|
+
# Select objective
|
|
191
|
+
try:
|
|
192
|
+
objectives = list_objectives(domain)
|
|
193
|
+
print(f"\nObjectives for '{domain}':")
|
|
194
|
+
for i, obj in enumerate(objectives, 1):
|
|
195
|
+
print(f" {i}. {obj}")
|
|
196
|
+
print()
|
|
197
|
+
|
|
198
|
+
obj_idx = int(input("Select objective (number, or 0 for any): ").strip())
|
|
199
|
+
if obj_idx == 0:
|
|
200
|
+
objective = None
|
|
201
|
+
else:
|
|
202
|
+
obj_idx -= 1
|
|
203
|
+
if obj_idx < 0 or obj_idx >= len(objectives):
|
|
204
|
+
print("⚠ Invalid selection.\n")
|
|
205
|
+
return
|
|
206
|
+
objective = objectives[obj_idx]
|
|
207
|
+
except (ValueError, EOFError):
|
|
208
|
+
print("⚠ Invalid input.\n")
|
|
209
|
+
return
|
|
210
|
+
|
|
211
|
+
# Generate
|
|
212
|
+
print("\nGenerating sequence...")
|
|
213
|
+
try:
|
|
214
|
+
result = self.generator.generate_for_context(
|
|
215
|
+
domain=domain, objective=objective, min_health=0.70
|
|
216
|
+
)
|
|
217
|
+
self._display_generated_sequence(result)
|
|
218
|
+
|
|
219
|
+
# Offer to analyze
|
|
220
|
+
if self._ask_yes_no("\nAnalyze this sequence in detail?"):
|
|
221
|
+
self._analyze_sequence(result.sequence)
|
|
222
|
+
|
|
223
|
+
except Exception as e:
|
|
224
|
+
print(f"✗ Generation failed: {e}\n")
|
|
225
|
+
|
|
226
|
+
def _generate_by_pattern(self) -> None:
|
|
227
|
+
"""Generate sequence by selecting structural pattern."""
|
|
228
|
+
print("\nCommon structural patterns:")
|
|
229
|
+
patterns = [
|
|
230
|
+
"BOOTSTRAP",
|
|
231
|
+
"THERAPEUTIC",
|
|
232
|
+
"STABILIZE",
|
|
233
|
+
"REGENERATIVE",
|
|
234
|
+
"EXPLORATION",
|
|
235
|
+
"TRANSFORMATIVE",
|
|
236
|
+
"COUPLING",
|
|
237
|
+
"SIMPLE",
|
|
238
|
+
]
|
|
239
|
+
for i, pattern in enumerate(patterns, 1):
|
|
240
|
+
print(f" {i}. {pattern}")
|
|
241
|
+
print()
|
|
242
|
+
|
|
243
|
+
try:
|
|
244
|
+
pattern_idx = int(input("Select pattern (number): ").strip()) - 1
|
|
245
|
+
if pattern_idx < 0 or pattern_idx >= len(patterns):
|
|
246
|
+
print("⚠ Invalid selection.\n")
|
|
247
|
+
return
|
|
248
|
+
pattern = patterns[pattern_idx]
|
|
249
|
+
except (ValueError, EOFError):
|
|
250
|
+
print("⚠ Invalid input.\n")
|
|
251
|
+
return
|
|
252
|
+
|
|
253
|
+
# Generate
|
|
254
|
+
print(f"\nGenerating {pattern} sequence...")
|
|
255
|
+
try:
|
|
256
|
+
result = self.generator.generate_for_pattern(
|
|
257
|
+
target_pattern=pattern, min_health=0.70
|
|
258
|
+
)
|
|
259
|
+
self._display_generated_sequence(result)
|
|
260
|
+
|
|
261
|
+
except Exception as e:
|
|
262
|
+
print(f"✗ Generation failed: {e}\n")
|
|
263
|
+
|
|
264
|
+
def _interactive_optimize(self) -> None:
|
|
265
|
+
"""Interactive sequence optimization."""
|
|
266
|
+
print("\n" + "─" * 60)
|
|
267
|
+
print("OPTIMIZE SEQUENCE")
|
|
268
|
+
print("─" * 60)
|
|
269
|
+
print("Enter the sequence you want to improve.")
|
|
270
|
+
print()
|
|
271
|
+
|
|
272
|
+
sequence_input = input("Current sequence: ").strip()
|
|
273
|
+
if not sequence_input:
|
|
274
|
+
print("⚠ Empty sequence. Returning to menu.\n")
|
|
275
|
+
return
|
|
276
|
+
|
|
277
|
+
current = self._parse_sequence_input(sequence_input)
|
|
278
|
+
|
|
279
|
+
# Ask for target health
|
|
280
|
+
try:
|
|
281
|
+
target_input = input(
|
|
282
|
+
"Target health score (0.0-1.0, or Enter for default): "
|
|
283
|
+
).strip()
|
|
284
|
+
target_health = float(target_input) if target_input else None
|
|
285
|
+
except ValueError:
|
|
286
|
+
print("⚠ Invalid health score. Using default.\n")
|
|
287
|
+
target_health = None
|
|
288
|
+
|
|
289
|
+
print("\nOptimizing...")
|
|
290
|
+
try:
|
|
291
|
+
improved, recommendations = self.generator.improve_sequence(
|
|
292
|
+
current, target_health=target_health
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
# Show results
|
|
296
|
+
current_health = self.analyzer.analyze_health(current)
|
|
297
|
+
improved_health = self.analyzer.analyze_health(improved)
|
|
298
|
+
|
|
299
|
+
self._display_optimization_result(
|
|
300
|
+
current, improved, current_health, improved_health, recommendations
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
except Exception as e:
|
|
304
|
+
print(f"✗ Optimization failed: {e}\n")
|
|
305
|
+
|
|
306
|
+
def _interactive_explore(self) -> None:
|
|
307
|
+
"""Interactive exploration of patterns and domains."""
|
|
308
|
+
print("\n" + "─" * 60)
|
|
309
|
+
print("EXPLORE")
|
|
310
|
+
print("─" * 60)
|
|
311
|
+
print()
|
|
312
|
+
print(" [d] List all domains")
|
|
313
|
+
print(" [o] List objectives for a domain")
|
|
314
|
+
print(" [p] Learn about structural patterns")
|
|
315
|
+
print(" [b] Back to main menu")
|
|
316
|
+
print()
|
|
317
|
+
|
|
318
|
+
choice = input("Select option: ").strip().lower()
|
|
319
|
+
|
|
320
|
+
if choice == "d":
|
|
321
|
+
self._list_domains()
|
|
322
|
+
elif choice == "o":
|
|
323
|
+
self._list_objectives_for_domain()
|
|
324
|
+
elif choice == "p":
|
|
325
|
+
self._explain_patterns()
|
|
326
|
+
elif choice == "b":
|
|
327
|
+
return
|
|
328
|
+
else:
|
|
329
|
+
print(f"⚠ Invalid choice: '{choice}'\n")
|
|
330
|
+
|
|
331
|
+
def _show_help(self) -> None:
|
|
332
|
+
"""Show help and documentation."""
|
|
333
|
+
print("\n" + "═" * 60)
|
|
334
|
+
print("HELP & DOCUMENTATION")
|
|
335
|
+
print("═" * 60)
|
|
336
|
+
print()
|
|
337
|
+
print("TNFR (Resonant Fractal Nature Theory) Operators:")
|
|
338
|
+
print()
|
|
339
|
+
print(" emission - Initiate resonant pattern (AL)")
|
|
340
|
+
print(" reception - Receive and integrate patterns (EN)")
|
|
341
|
+
print(" coherence - Stabilize structure (IL)")
|
|
342
|
+
print(" dissonance - Introduce controlled instability (OZ)")
|
|
343
|
+
print(" coupling - Create structural links (UM)")
|
|
344
|
+
print(" resonance - Amplify and propagate (RA)")
|
|
345
|
+
print(" silence - Freeze evolution temporarily (SHA)")
|
|
346
|
+
print(" expansion - Increase complexity (VAL)")
|
|
347
|
+
print(" contraction - Reduce complexity (NUL)")
|
|
348
|
+
print(" self_organization - Spontaneous pattern formation (THOL)")
|
|
349
|
+
print(" mutation - Phase transformation (ZHIR)")
|
|
350
|
+
print(" transition - Movement between states (NAV)")
|
|
351
|
+
print(" recursivity - Nested operations (REMESH)")
|
|
352
|
+
print()
|
|
353
|
+
print("Health Metrics:")
|
|
354
|
+
print()
|
|
355
|
+
print(" Overall Health - Composite quality score (0.0-1.0)")
|
|
356
|
+
print(" Coherence Index - Sequential flow quality")
|
|
357
|
+
print(" Balance Score - Stability/instability equilibrium")
|
|
358
|
+
print(" Sustainability - Long-term maintenance capacity")
|
|
359
|
+
print()
|
|
360
|
+
print("For more information, visit:")
|
|
361
|
+
print(" https://github.com/fermga/TNFR-Python-Engine")
|
|
362
|
+
print()
|
|
363
|
+
|
|
364
|
+
# Helper methods
|
|
365
|
+
|
|
366
|
+
def _parse_sequence_input(self, sequence_input: str) -> list[str]:
|
|
367
|
+
"""Parse sequence from user input, handling multiple separators."""
|
|
368
|
+
# Replace commas with spaces and split
|
|
369
|
+
sequence_input = sequence_input.replace(",", " ")
|
|
370
|
+
return [op.strip() for op in sequence_input.split() if op.strip()]
|
|
371
|
+
|
|
372
|
+
def _display_success(
|
|
373
|
+
self, result: SequenceValidationResult, sequence: list[str]
|
|
374
|
+
) -> None:
|
|
375
|
+
"""Display successful validation with health metrics."""
|
|
376
|
+
print()
|
|
377
|
+
print("✓ VALID SEQUENCE")
|
|
378
|
+
print()
|
|
379
|
+
|
|
380
|
+
if result.health_metrics:
|
|
381
|
+
self._display_health_metrics(result.health_metrics)
|
|
382
|
+
|
|
383
|
+
def _display_health_metrics(self, health: SequenceHealthMetrics) -> None:
|
|
384
|
+
"""Display health metrics with visual formatting."""
|
|
385
|
+
print("┌─ Health Metrics " + "─" * 41 + "┐")
|
|
386
|
+
|
|
387
|
+
# Overall health
|
|
388
|
+
icon = self._health_icon(health.overall_health)
|
|
389
|
+
bar = self._health_bar(health.overall_health)
|
|
390
|
+
status = self._health_status(health.overall_health)
|
|
391
|
+
print(
|
|
392
|
+
f"│ Overall Health: {bar} {health.overall_health:.2f} {icon} ({status})"
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
# Individual metrics
|
|
396
|
+
print(
|
|
397
|
+
f"│ Coherence Index: {self._health_bar(health.coherence_index)} {health.coherence_index:.2f}"
|
|
398
|
+
)
|
|
399
|
+
print(
|
|
400
|
+
f"│ Balance Score: {self._health_bar(health.balance_score)} {health.balance_score:.2f}"
|
|
401
|
+
)
|
|
402
|
+
print(
|
|
403
|
+
f"│ Sustainability: {self._health_bar(health.sustainability_index)} {health.sustainability_index:.2f}"
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
# Pattern
|
|
407
|
+
print(f"│ Pattern Detected: {health.dominant_pattern.upper()}")
|
|
408
|
+
print(f"│ Sequence Length: {health.sequence_length}")
|
|
409
|
+
|
|
410
|
+
print("└" + "─" * 58 + "┘")
|
|
411
|
+
|
|
412
|
+
def _health_bar(self, value: float, width: int = 10) -> str:
|
|
413
|
+
"""Generate ASCII bar chart for health metric."""
|
|
414
|
+
filled = int(value * width)
|
|
415
|
+
return "█" * filled + "░" * (width - filled)
|
|
416
|
+
|
|
417
|
+
def _health_icon(self, value: float) -> str:
|
|
418
|
+
"""Get icon for health value."""
|
|
419
|
+
if value >= 0.8:
|
|
420
|
+
return "✓"
|
|
421
|
+
elif value >= 0.6:
|
|
422
|
+
return "⚠"
|
|
423
|
+
else:
|
|
424
|
+
return "✗"
|
|
425
|
+
|
|
426
|
+
def _health_status(self, value: float) -> str:
|
|
427
|
+
"""Get status text for health value."""
|
|
428
|
+
if value >= 0.8:
|
|
429
|
+
return "Excellent"
|
|
430
|
+
elif value >= 0.7:
|
|
431
|
+
return "Good"
|
|
432
|
+
elif value >= 0.6:
|
|
433
|
+
return "Moderate"
|
|
434
|
+
else:
|
|
435
|
+
return "Needs Improvement"
|
|
436
|
+
|
|
437
|
+
def _display_error(self, result: SequenceValidationResult) -> None:
|
|
438
|
+
"""Display validation error with details."""
|
|
439
|
+
print()
|
|
440
|
+
print("✗ INVALID SEQUENCE")
|
|
441
|
+
print()
|
|
442
|
+
print(f"Error: {result.message}")
|
|
443
|
+
if result.error:
|
|
444
|
+
print(f"Type: {type(result.error).__name__}")
|
|
445
|
+
print()
|
|
446
|
+
|
|
447
|
+
def _suggest_improvements(
|
|
448
|
+
self, sequence: list[str], health: SequenceHealthMetrics
|
|
449
|
+
) -> None:
|
|
450
|
+
"""Suggest improvements for moderate health sequences."""
|
|
451
|
+
if not health.recommendations:
|
|
452
|
+
return
|
|
453
|
+
|
|
454
|
+
print()
|
|
455
|
+
print("💡 Recommendations:")
|
|
456
|
+
for i, rec in enumerate(health.recommendations[:3], 1):
|
|
457
|
+
print(f" {i}. {rec}")
|
|
458
|
+
print()
|
|
459
|
+
|
|
460
|
+
def _suggest_fixes(self, sequence: list[str], error: Optional[Exception]) -> None:
|
|
461
|
+
"""Suggest fixes for validation errors."""
|
|
462
|
+
print("💡 Suggestions:")
|
|
463
|
+
print(" - Check operator spelling (e.g., 'emission' not 'emmision')")
|
|
464
|
+
print(" - Ensure sequence starts with emission or reception")
|
|
465
|
+
print(" - End with a stabilizer (coherence, silence, self_organization)")
|
|
466
|
+
print()
|
|
467
|
+
|
|
468
|
+
def _display_exception(self, error: Exception) -> None:
|
|
469
|
+
"""Display unexpected exception."""
|
|
470
|
+
print()
|
|
471
|
+
print(f"✗ Unexpected error: {error}")
|
|
472
|
+
print()
|
|
473
|
+
|
|
474
|
+
def _display_generated_sequence(self, result: GenerationResult) -> None:
|
|
475
|
+
"""Display generated sequence with details."""
|
|
476
|
+
print()
|
|
477
|
+
print("✓ GENERATED SEQUENCE")
|
|
478
|
+
print()
|
|
479
|
+
print(f"Sequence: {' → '.join(result.sequence)}")
|
|
480
|
+
print(
|
|
481
|
+
f"Health: {result.health_score:.2f} {self._health_icon(result.health_score)}"
|
|
482
|
+
)
|
|
483
|
+
print(f"Pattern: {result.detected_pattern.upper()}")
|
|
484
|
+
|
|
485
|
+
if result.domain:
|
|
486
|
+
print(f"Domain: {result.domain}")
|
|
487
|
+
if result.objective:
|
|
488
|
+
print(f"Objective: {result.objective}")
|
|
489
|
+
|
|
490
|
+
if result.recommendations:
|
|
491
|
+
print()
|
|
492
|
+
print("💡 Recommendations:")
|
|
493
|
+
for i, rec in enumerate(result.recommendations[:3], 1):
|
|
494
|
+
print(f" {i}. {rec}")
|
|
495
|
+
print()
|
|
496
|
+
|
|
497
|
+
def _analyze_sequence(self, sequence: list[str]) -> None:
|
|
498
|
+
"""Perform detailed analysis on a sequence."""
|
|
499
|
+
print("\n" + "─" * 60)
|
|
500
|
+
print("DETAILED ANALYSIS")
|
|
501
|
+
print("─" * 60)
|
|
502
|
+
|
|
503
|
+
health = self.analyzer.analyze_health(sequence)
|
|
504
|
+
self._display_health_metrics(health)
|
|
505
|
+
|
|
506
|
+
if health.recommendations:
|
|
507
|
+
print()
|
|
508
|
+
print("All Recommendations:")
|
|
509
|
+
for i, rec in enumerate(health.recommendations, 1):
|
|
510
|
+
print(f" {i}. {rec}")
|
|
511
|
+
print()
|
|
512
|
+
|
|
513
|
+
def _display_optimization_result(
|
|
514
|
+
self,
|
|
515
|
+
current: list[str],
|
|
516
|
+
improved: list[str],
|
|
517
|
+
current_health: SequenceHealthMetrics,
|
|
518
|
+
improved_health: SequenceHealthMetrics,
|
|
519
|
+
recommendations: list[str],
|
|
520
|
+
) -> None:
|
|
521
|
+
"""Display optimization result with before/after comparison."""
|
|
522
|
+
print()
|
|
523
|
+
print("✓ OPTIMIZATION COMPLETE")
|
|
524
|
+
print()
|
|
525
|
+
print(f"Original: {' → '.join(current)}")
|
|
526
|
+
print(
|
|
527
|
+
f" Health: {current_health.overall_health:.2f} {self._health_icon(current_health.overall_health)}"
|
|
528
|
+
)
|
|
529
|
+
print()
|
|
530
|
+
print(f"Improved: {' → '.join(improved)}")
|
|
531
|
+
print(
|
|
532
|
+
f" Health: {improved_health.overall_health:.2f} {self._health_icon(improved_health.overall_health)}"
|
|
533
|
+
)
|
|
534
|
+
|
|
535
|
+
delta = improved_health.overall_health - current_health.overall_health
|
|
536
|
+
if delta > 0:
|
|
537
|
+
print(f" Delta: +{delta:.2f} ✓")
|
|
538
|
+
else:
|
|
539
|
+
print(f" Delta: {delta:.2f}")
|
|
540
|
+
|
|
541
|
+
if recommendations:
|
|
542
|
+
print()
|
|
543
|
+
print("Changes made:")
|
|
544
|
+
for i, rec in enumerate(recommendations, 1):
|
|
545
|
+
print(f" {i}. {rec}")
|
|
546
|
+
print()
|
|
547
|
+
|
|
548
|
+
def _list_domains(self) -> None:
|
|
549
|
+
"""List all available domains."""
|
|
550
|
+
domains = list_domains()
|
|
551
|
+
print()
|
|
552
|
+
print("Available Domains:")
|
|
553
|
+
for domain in domains:
|
|
554
|
+
print(f" • {domain}")
|
|
555
|
+
print()
|
|
556
|
+
|
|
557
|
+
def _list_objectives_for_domain(self) -> None:
|
|
558
|
+
"""List objectives for a specific domain."""
|
|
559
|
+
domain = input("\nDomain name: ").strip()
|
|
560
|
+
try:
|
|
561
|
+
objectives = list_objectives(domain)
|
|
562
|
+
print()
|
|
563
|
+
print(f"Objectives for '{domain}':")
|
|
564
|
+
for obj in objectives:
|
|
565
|
+
print(f" • {obj}")
|
|
566
|
+
print()
|
|
567
|
+
except KeyError:
|
|
568
|
+
print(f"\n⚠ Unknown domain: '{domain}'\n")
|
|
569
|
+
|
|
570
|
+
def _explain_patterns(self) -> None:
|
|
571
|
+
"""Explain structural patterns."""
|
|
572
|
+
print()
|
|
573
|
+
print("Structural Patterns:")
|
|
574
|
+
print()
|
|
575
|
+
print(" BOOTSTRAP - Initialize new nodes/systems")
|
|
576
|
+
print(" THERAPEUTIC - Healing and stabilization")
|
|
577
|
+
print(" STABILIZE - Maintain coherent structure")
|
|
578
|
+
print(" REGENERATIVE - Self-renewal and growth")
|
|
579
|
+
print(" EXPLORATION - Discovery with dissonance")
|
|
580
|
+
print(" TRANSFORMATIVE - Phase transitions")
|
|
581
|
+
print(" COUPLING - Network formation")
|
|
582
|
+
print(" SIMPLE - Minimal effective sequences")
|
|
583
|
+
print()
|
|
584
|
+
|
|
585
|
+
def _ask_yes_no(self, prompt: str) -> bool:
|
|
586
|
+
"""Ask yes/no question."""
|
|
587
|
+
response = input(f"{prompt} (y/n): ").strip().lower()
|
|
588
|
+
return response in ("y", "yes")
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
def run_interactive_validator(seed: Optional[int] = None) -> int:
|
|
592
|
+
"""Run the interactive validator session.
|
|
593
|
+
|
|
594
|
+
Parameters
|
|
595
|
+
----------
|
|
596
|
+
seed : int, optional
|
|
597
|
+
Random seed for deterministic generation.
|
|
598
|
+
|
|
599
|
+
Returns
|
|
600
|
+
-------
|
|
601
|
+
int
|
|
602
|
+
Exit code (0 for success).
|
|
603
|
+
"""
|
|
604
|
+
validator = TNFRInteractiveValidator(seed=seed)
|
|
605
|
+
try:
|
|
606
|
+
validator.run_interactive_session()
|
|
607
|
+
return 0
|
|
608
|
+
except Exception as e:
|
|
609
|
+
print(f"\n✗ Fatal error: {e}", file=sys.stderr)
|
|
610
|
+
return 1
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
if __name__ == "__main__":
|
|
614
|
+
sys.exit(run_interactive_validator())
|