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.

Files changed (360) hide show
  1. tnfr/__init__.py +375 -56
  2. tnfr/__init__.pyi +33 -0
  3. tnfr/_compat.py +10 -0
  4. tnfr/_generated_version.py +34 -0
  5. tnfr/_version.py +49 -0
  6. tnfr/_version.pyi +7 -0
  7. tnfr/alias.py +723 -0
  8. tnfr/alias.pyi +108 -0
  9. tnfr/backends/__init__.py +354 -0
  10. tnfr/backends/jax_backend.py +173 -0
  11. tnfr/backends/numpy_backend.py +238 -0
  12. tnfr/backends/optimized_numpy.py +420 -0
  13. tnfr/backends/torch_backend.py +408 -0
  14. tnfr/cache.py +171 -0
  15. tnfr/cache.pyi +13 -0
  16. tnfr/cli/__init__.py +110 -0
  17. tnfr/cli/__init__.pyi +26 -0
  18. tnfr/cli/arguments.py +489 -0
  19. tnfr/cli/arguments.pyi +29 -0
  20. tnfr/cli/execution.py +914 -0
  21. tnfr/cli/execution.pyi +70 -0
  22. tnfr/cli/interactive_validator.py +614 -0
  23. tnfr/cli/utils.py +51 -0
  24. tnfr/cli/utils.pyi +7 -0
  25. tnfr/cli/validate.py +236 -0
  26. tnfr/compat/__init__.py +85 -0
  27. tnfr/compat/dataclass.py +136 -0
  28. tnfr/compat/jsonschema_stub.py +61 -0
  29. tnfr/compat/matplotlib_stub.py +73 -0
  30. tnfr/compat/numpy_stub.py +155 -0
  31. tnfr/config/__init__.py +224 -0
  32. tnfr/config/__init__.pyi +10 -0
  33. tnfr/config/constants.py +104 -0
  34. tnfr/config/constants.pyi +12 -0
  35. tnfr/config/defaults.py +54 -0
  36. tnfr/config/defaults_core.py +212 -0
  37. tnfr/config/defaults_init.py +33 -0
  38. tnfr/config/defaults_metric.py +104 -0
  39. tnfr/config/feature_flags.py +81 -0
  40. tnfr/config/feature_flags.pyi +16 -0
  41. tnfr/config/glyph_constants.py +31 -0
  42. tnfr/config/init.py +77 -0
  43. tnfr/config/init.pyi +8 -0
  44. tnfr/config/operator_names.py +254 -0
  45. tnfr/config/operator_names.pyi +36 -0
  46. tnfr/config/physics_derivation.py +354 -0
  47. tnfr/config/presets.py +83 -0
  48. tnfr/config/presets.pyi +7 -0
  49. tnfr/config/security.py +927 -0
  50. tnfr/config/thresholds.py +114 -0
  51. tnfr/config/tnfr_config.py +498 -0
  52. tnfr/constants/__init__.py +92 -0
  53. tnfr/constants/__init__.pyi +92 -0
  54. tnfr/constants/aliases.py +33 -0
  55. tnfr/constants/aliases.pyi +27 -0
  56. tnfr/constants/init.py +33 -0
  57. tnfr/constants/init.pyi +12 -0
  58. tnfr/constants/metric.py +104 -0
  59. tnfr/constants/metric.pyi +19 -0
  60. tnfr/core/__init__.py +33 -0
  61. tnfr/core/container.py +226 -0
  62. tnfr/core/default_implementations.py +329 -0
  63. tnfr/core/interfaces.py +279 -0
  64. tnfr/dynamics/__init__.py +238 -0
  65. tnfr/dynamics/__init__.pyi +83 -0
  66. tnfr/dynamics/adaptation.py +267 -0
  67. tnfr/dynamics/adaptation.pyi +7 -0
  68. tnfr/dynamics/adaptive_sequences.py +189 -0
  69. tnfr/dynamics/adaptive_sequences.pyi +14 -0
  70. tnfr/dynamics/aliases.py +23 -0
  71. tnfr/dynamics/aliases.pyi +19 -0
  72. tnfr/dynamics/bifurcation.py +232 -0
  73. tnfr/dynamics/canonical.py +229 -0
  74. tnfr/dynamics/canonical.pyi +48 -0
  75. tnfr/dynamics/coordination.py +385 -0
  76. tnfr/dynamics/coordination.pyi +25 -0
  77. tnfr/dynamics/dnfr.py +3034 -0
  78. tnfr/dynamics/dnfr.pyi +26 -0
  79. tnfr/dynamics/dynamic_limits.py +225 -0
  80. tnfr/dynamics/feedback.py +252 -0
  81. tnfr/dynamics/feedback.pyi +24 -0
  82. tnfr/dynamics/fused_dnfr.py +454 -0
  83. tnfr/dynamics/homeostasis.py +157 -0
  84. tnfr/dynamics/homeostasis.pyi +14 -0
  85. tnfr/dynamics/integrators.py +661 -0
  86. tnfr/dynamics/integrators.pyi +36 -0
  87. tnfr/dynamics/learning.py +310 -0
  88. tnfr/dynamics/learning.pyi +33 -0
  89. tnfr/dynamics/metabolism.py +254 -0
  90. tnfr/dynamics/nbody.py +796 -0
  91. tnfr/dynamics/nbody_tnfr.py +783 -0
  92. tnfr/dynamics/propagation.py +326 -0
  93. tnfr/dynamics/runtime.py +908 -0
  94. tnfr/dynamics/runtime.pyi +77 -0
  95. tnfr/dynamics/sampling.py +36 -0
  96. tnfr/dynamics/sampling.pyi +7 -0
  97. tnfr/dynamics/selectors.py +711 -0
  98. tnfr/dynamics/selectors.pyi +85 -0
  99. tnfr/dynamics/structural_clip.py +207 -0
  100. tnfr/errors/__init__.py +37 -0
  101. tnfr/errors/contextual.py +492 -0
  102. tnfr/execution.py +223 -0
  103. tnfr/execution.pyi +45 -0
  104. tnfr/extensions/__init__.py +205 -0
  105. tnfr/extensions/__init__.pyi +18 -0
  106. tnfr/extensions/base.py +173 -0
  107. tnfr/extensions/base.pyi +35 -0
  108. tnfr/extensions/business/__init__.py +71 -0
  109. tnfr/extensions/business/__init__.pyi +11 -0
  110. tnfr/extensions/business/cookbook.py +88 -0
  111. tnfr/extensions/business/cookbook.pyi +8 -0
  112. tnfr/extensions/business/health_analyzers.py +202 -0
  113. tnfr/extensions/business/health_analyzers.pyi +9 -0
  114. tnfr/extensions/business/patterns.py +183 -0
  115. tnfr/extensions/business/patterns.pyi +8 -0
  116. tnfr/extensions/medical/__init__.py +73 -0
  117. tnfr/extensions/medical/__init__.pyi +11 -0
  118. tnfr/extensions/medical/cookbook.py +88 -0
  119. tnfr/extensions/medical/cookbook.pyi +8 -0
  120. tnfr/extensions/medical/health_analyzers.py +181 -0
  121. tnfr/extensions/medical/health_analyzers.pyi +9 -0
  122. tnfr/extensions/medical/patterns.py +163 -0
  123. tnfr/extensions/medical/patterns.pyi +8 -0
  124. tnfr/flatten.py +262 -0
  125. tnfr/flatten.pyi +21 -0
  126. tnfr/gamma.py +354 -0
  127. tnfr/gamma.pyi +36 -0
  128. tnfr/glyph_history.py +377 -0
  129. tnfr/glyph_history.pyi +35 -0
  130. tnfr/glyph_runtime.py +19 -0
  131. tnfr/glyph_runtime.pyi +8 -0
  132. tnfr/immutable.py +218 -0
  133. tnfr/immutable.pyi +36 -0
  134. tnfr/initialization.py +203 -0
  135. tnfr/initialization.pyi +65 -0
  136. tnfr/io.py +10 -0
  137. tnfr/io.pyi +13 -0
  138. tnfr/locking.py +37 -0
  139. tnfr/locking.pyi +7 -0
  140. tnfr/mathematics/__init__.py +79 -0
  141. tnfr/mathematics/backend.py +453 -0
  142. tnfr/mathematics/backend.pyi +99 -0
  143. tnfr/mathematics/dynamics.py +408 -0
  144. tnfr/mathematics/dynamics.pyi +90 -0
  145. tnfr/mathematics/epi.py +391 -0
  146. tnfr/mathematics/epi.pyi +65 -0
  147. tnfr/mathematics/generators.py +242 -0
  148. tnfr/mathematics/generators.pyi +29 -0
  149. tnfr/mathematics/metrics.py +119 -0
  150. tnfr/mathematics/metrics.pyi +16 -0
  151. tnfr/mathematics/operators.py +239 -0
  152. tnfr/mathematics/operators.pyi +59 -0
  153. tnfr/mathematics/operators_factory.py +124 -0
  154. tnfr/mathematics/operators_factory.pyi +11 -0
  155. tnfr/mathematics/projection.py +87 -0
  156. tnfr/mathematics/projection.pyi +33 -0
  157. tnfr/mathematics/runtime.py +182 -0
  158. tnfr/mathematics/runtime.pyi +64 -0
  159. tnfr/mathematics/spaces.py +256 -0
  160. tnfr/mathematics/spaces.pyi +83 -0
  161. tnfr/mathematics/transforms.py +305 -0
  162. tnfr/mathematics/transforms.pyi +62 -0
  163. tnfr/metrics/__init__.py +79 -0
  164. tnfr/metrics/__init__.pyi +20 -0
  165. tnfr/metrics/buffer_cache.py +163 -0
  166. tnfr/metrics/buffer_cache.pyi +24 -0
  167. tnfr/metrics/cache_utils.py +214 -0
  168. tnfr/metrics/coherence.py +2009 -0
  169. tnfr/metrics/coherence.pyi +129 -0
  170. tnfr/metrics/common.py +158 -0
  171. tnfr/metrics/common.pyi +35 -0
  172. tnfr/metrics/core.py +316 -0
  173. tnfr/metrics/core.pyi +13 -0
  174. tnfr/metrics/diagnosis.py +833 -0
  175. tnfr/metrics/diagnosis.pyi +86 -0
  176. tnfr/metrics/emergence.py +245 -0
  177. tnfr/metrics/export.py +179 -0
  178. tnfr/metrics/export.pyi +7 -0
  179. tnfr/metrics/glyph_timing.py +379 -0
  180. tnfr/metrics/glyph_timing.pyi +81 -0
  181. tnfr/metrics/learning_metrics.py +280 -0
  182. tnfr/metrics/learning_metrics.pyi +21 -0
  183. tnfr/metrics/phase_coherence.py +351 -0
  184. tnfr/metrics/phase_compatibility.py +349 -0
  185. tnfr/metrics/reporting.py +183 -0
  186. tnfr/metrics/reporting.pyi +25 -0
  187. tnfr/metrics/sense_index.py +1203 -0
  188. tnfr/metrics/sense_index.pyi +9 -0
  189. tnfr/metrics/trig.py +373 -0
  190. tnfr/metrics/trig.pyi +13 -0
  191. tnfr/metrics/trig_cache.py +233 -0
  192. tnfr/metrics/trig_cache.pyi +10 -0
  193. tnfr/multiscale/__init__.py +32 -0
  194. tnfr/multiscale/hierarchical.py +517 -0
  195. tnfr/node.py +763 -0
  196. tnfr/node.pyi +139 -0
  197. tnfr/observers.py +255 -130
  198. tnfr/observers.pyi +31 -0
  199. tnfr/ontosim.py +144 -137
  200. tnfr/ontosim.pyi +28 -0
  201. tnfr/operators/__init__.py +1672 -0
  202. tnfr/operators/__init__.pyi +31 -0
  203. tnfr/operators/algebra.py +277 -0
  204. tnfr/operators/canonical_patterns.py +420 -0
  205. tnfr/operators/cascade.py +267 -0
  206. tnfr/operators/cycle_detection.py +358 -0
  207. tnfr/operators/definitions.py +4108 -0
  208. tnfr/operators/definitions.pyi +78 -0
  209. tnfr/operators/grammar.py +1164 -0
  210. tnfr/operators/grammar.pyi +140 -0
  211. tnfr/operators/hamiltonian.py +710 -0
  212. tnfr/operators/health_analyzer.py +809 -0
  213. tnfr/operators/jitter.py +272 -0
  214. tnfr/operators/jitter.pyi +11 -0
  215. tnfr/operators/lifecycle.py +314 -0
  216. tnfr/operators/metabolism.py +618 -0
  217. tnfr/operators/metrics.py +2138 -0
  218. tnfr/operators/network_analysis/__init__.py +27 -0
  219. tnfr/operators/network_analysis/source_detection.py +186 -0
  220. tnfr/operators/nodal_equation.py +395 -0
  221. tnfr/operators/pattern_detection.py +660 -0
  222. tnfr/operators/patterns.py +669 -0
  223. tnfr/operators/postconditions/__init__.py +38 -0
  224. tnfr/operators/postconditions/mutation.py +236 -0
  225. tnfr/operators/preconditions/__init__.py +1226 -0
  226. tnfr/operators/preconditions/coherence.py +305 -0
  227. tnfr/operators/preconditions/dissonance.py +236 -0
  228. tnfr/operators/preconditions/emission.py +128 -0
  229. tnfr/operators/preconditions/mutation.py +580 -0
  230. tnfr/operators/preconditions/reception.py +125 -0
  231. tnfr/operators/preconditions/resonance.py +364 -0
  232. tnfr/operators/registry.py +74 -0
  233. tnfr/operators/registry.pyi +9 -0
  234. tnfr/operators/remesh.py +1809 -0
  235. tnfr/operators/remesh.pyi +26 -0
  236. tnfr/operators/structural_units.py +268 -0
  237. tnfr/operators/unified_grammar.py +105 -0
  238. tnfr/parallel/__init__.py +54 -0
  239. tnfr/parallel/auto_scaler.py +234 -0
  240. tnfr/parallel/distributed.py +384 -0
  241. tnfr/parallel/engine.py +238 -0
  242. tnfr/parallel/gpu_engine.py +420 -0
  243. tnfr/parallel/monitoring.py +248 -0
  244. tnfr/parallel/partitioner.py +459 -0
  245. tnfr/py.typed +0 -0
  246. tnfr/recipes/__init__.py +22 -0
  247. tnfr/recipes/cookbook.py +743 -0
  248. tnfr/rng.py +178 -0
  249. tnfr/rng.pyi +26 -0
  250. tnfr/schemas/__init__.py +8 -0
  251. tnfr/schemas/grammar.json +94 -0
  252. tnfr/sdk/__init__.py +107 -0
  253. tnfr/sdk/__init__.pyi +19 -0
  254. tnfr/sdk/adaptive_system.py +173 -0
  255. tnfr/sdk/adaptive_system.pyi +21 -0
  256. tnfr/sdk/builders.py +370 -0
  257. tnfr/sdk/builders.pyi +51 -0
  258. tnfr/sdk/fluent.py +1121 -0
  259. tnfr/sdk/fluent.pyi +74 -0
  260. tnfr/sdk/templates.py +342 -0
  261. tnfr/sdk/templates.pyi +41 -0
  262. tnfr/sdk/utils.py +341 -0
  263. tnfr/secure_config.py +46 -0
  264. tnfr/security/__init__.py +70 -0
  265. tnfr/security/database.py +514 -0
  266. tnfr/security/subprocess.py +503 -0
  267. tnfr/security/validation.py +290 -0
  268. tnfr/selector.py +247 -0
  269. tnfr/selector.pyi +19 -0
  270. tnfr/sense.py +378 -0
  271. tnfr/sense.pyi +23 -0
  272. tnfr/services/__init__.py +17 -0
  273. tnfr/services/orchestrator.py +325 -0
  274. tnfr/sparse/__init__.py +39 -0
  275. tnfr/sparse/representations.py +492 -0
  276. tnfr/structural.py +705 -0
  277. tnfr/structural.pyi +83 -0
  278. tnfr/telemetry/__init__.py +35 -0
  279. tnfr/telemetry/cache_metrics.py +226 -0
  280. tnfr/telemetry/cache_metrics.pyi +64 -0
  281. tnfr/telemetry/nu_f.py +422 -0
  282. tnfr/telemetry/nu_f.pyi +108 -0
  283. tnfr/telemetry/verbosity.py +36 -0
  284. tnfr/telemetry/verbosity.pyi +15 -0
  285. tnfr/tokens.py +58 -0
  286. tnfr/tokens.pyi +36 -0
  287. tnfr/tools/__init__.py +20 -0
  288. tnfr/tools/domain_templates.py +478 -0
  289. tnfr/tools/sequence_generator.py +846 -0
  290. tnfr/topology/__init__.py +13 -0
  291. tnfr/topology/asymmetry.py +151 -0
  292. tnfr/trace.py +543 -0
  293. tnfr/trace.pyi +42 -0
  294. tnfr/tutorials/__init__.py +38 -0
  295. tnfr/tutorials/autonomous_evolution.py +285 -0
  296. tnfr/tutorials/interactive.py +1576 -0
  297. tnfr/tutorials/structural_metabolism.py +238 -0
  298. tnfr/types.py +775 -0
  299. tnfr/types.pyi +357 -0
  300. tnfr/units.py +68 -0
  301. tnfr/units.pyi +13 -0
  302. tnfr/utils/__init__.py +282 -0
  303. tnfr/utils/__init__.pyi +215 -0
  304. tnfr/utils/cache.py +4223 -0
  305. tnfr/utils/cache.pyi +470 -0
  306. tnfr/utils/callbacks.py +375 -0
  307. tnfr/utils/callbacks.pyi +49 -0
  308. tnfr/utils/chunks.py +108 -0
  309. tnfr/utils/chunks.pyi +22 -0
  310. tnfr/utils/data.py +428 -0
  311. tnfr/utils/data.pyi +74 -0
  312. tnfr/utils/graph.py +85 -0
  313. tnfr/utils/graph.pyi +10 -0
  314. tnfr/utils/init.py +821 -0
  315. tnfr/utils/init.pyi +80 -0
  316. tnfr/utils/io.py +559 -0
  317. tnfr/utils/io.pyi +66 -0
  318. tnfr/utils/numeric.py +114 -0
  319. tnfr/utils/numeric.pyi +21 -0
  320. tnfr/validation/__init__.py +257 -0
  321. tnfr/validation/__init__.pyi +85 -0
  322. tnfr/validation/compatibility.py +460 -0
  323. tnfr/validation/compatibility.pyi +6 -0
  324. tnfr/validation/config.py +73 -0
  325. tnfr/validation/graph.py +139 -0
  326. tnfr/validation/graph.pyi +18 -0
  327. tnfr/validation/input_validation.py +755 -0
  328. tnfr/validation/invariants.py +712 -0
  329. tnfr/validation/rules.py +253 -0
  330. tnfr/validation/rules.pyi +44 -0
  331. tnfr/validation/runtime.py +279 -0
  332. tnfr/validation/runtime.pyi +28 -0
  333. tnfr/validation/sequence_validator.py +162 -0
  334. tnfr/validation/soft_filters.py +170 -0
  335. tnfr/validation/soft_filters.pyi +32 -0
  336. tnfr/validation/spectral.py +164 -0
  337. tnfr/validation/spectral.pyi +42 -0
  338. tnfr/validation/validator.py +1266 -0
  339. tnfr/validation/window.py +39 -0
  340. tnfr/validation/window.pyi +1 -0
  341. tnfr/visualization/__init__.py +98 -0
  342. tnfr/visualization/cascade_viz.py +256 -0
  343. tnfr/visualization/hierarchy.py +284 -0
  344. tnfr/visualization/sequence_plotter.py +784 -0
  345. tnfr/viz/__init__.py +60 -0
  346. tnfr/viz/matplotlib.py +278 -0
  347. tnfr/viz/matplotlib.pyi +35 -0
  348. tnfr-8.5.0.dist-info/METADATA +573 -0
  349. tnfr-8.5.0.dist-info/RECORD +353 -0
  350. tnfr-8.5.0.dist-info/entry_points.txt +3 -0
  351. tnfr-3.0.3.dist-info/licenses/LICENSE.txt → tnfr-8.5.0.dist-info/licenses/LICENSE.md +1 -1
  352. tnfr/constants.py +0 -183
  353. tnfr/dynamics.py +0 -543
  354. tnfr/helpers.py +0 -198
  355. tnfr/main.py +0 -37
  356. tnfr/operators.py +0 -296
  357. tnfr-3.0.3.dist-info/METADATA +0 -35
  358. tnfr-3.0.3.dist-info/RECORD +0 -13
  359. {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
  360. {tnfr-3.0.3.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())