TNFR Logo
TheoryLearnSoftwareResearch

On this page

TNFR

Resonant Fractal Nature Theory — a mathematical framework for coherent patterns on graph-coupled networks.

About
  • Project history
  • Editorial policy
  • Contact
Resources
  • GitHub
  • PyPI
  • DOI · Zenodo
Legal
  • MIT License
  • Citation
© 2026 TNFR project — MIT licensed.DOI 10.5281/zenodo.17602860
docs
grammar
PHYSICS_VERIFICATION.md
API_CONTRACTS.mdCANONICAL_OZ_SEQUENCES.mdEMPIRICAL_CONFRONTATION_EEG.mdREADME.mdSTRUCTURAL_FIELDS_TETRAD.mdSTRUCTURAL_INTERFACE_THEORY.md
theory
APPLIED_STRUCTURAL_ANALYSIS.mdCATALOG_TYPE_HYGIENE_PROGRAMME.mdDISSIPATIVE_AND_OPEN_SYSTEMS.mdEMERGENT_ONTOLOGY.mdEXTENDED_FIELDS_AND_DERIVED_QUANTITIES.mdFUNDAMENTAL_THEORY.mdGAUGE_SYMMETRY_AND_UNIFICATION.mdGLOSSARY.mdMATHEMATICAL_DYNAMICS_BASIS.mdMINIMAL_STRUCTURAL_DEGREES.mdNUCLEUS_A_PRIME_LADDER_ATLAS.mdNUCLEUS_B_EQUIVARIANCE_OBSTRUCTIONS.mdPHYSICAL_REGIME_CORRESPONDENCES.mdREADME.mdREMESH_INFINITY_DERIVATION.mdSTRUCTURAL_CONSERVATION_THEOREM.mdSTRUCTURAL_OPERATORS.mdSTRUCTURAL_STABILITY_AND_DYNAMICS.mdTNFR_BSD_RESEARCH_NOTES.mdTNFR_HODGE_RESEARCH_NOTES.mdTNFR_NAVIER_STOKES_RESEARCH_NOTES.mdTNFR_NUMBER_THEORY.mdTNFR_P_VS_NP_RESEARCH_NOTES.mdTNFR_RIEMANN_RESEARCH_NOTES.mdTNFR_VARIATIONAL_PRINCIPLE.mdTNFR_YANG_MILLS_RESEARCH_NOTES.mdTNFR.pdfUNIFIED_GRAMMAR_RULES.md
factorization-lab
analysis
analyze_patterns.pycertificate_manifest.py
benchmarks
benchmark_analysis.pybenchmark_expansion_suite.pyfull_spectrum_factorization.pypaley_gap_extended.pypaley_gap_smoke.pytest_benchmark_suite.py
demos
experiment_contexts
exp_0b1663cd19b7.jsonexp_0bf0054b7474.jsonexp_75a4c8ca616a.jsonexp_848ee0fd1857.jsonexp_f6fe00562193.jsonexp_fdf3da424e1e.json
failure_telemetry_batch.pyfeedback_integration_demo.pyintegration_demo_snapshots.dbseed_management_integration_demo.pysnapshot_integration_demo.pytrajectory_143.jsontrajectory_77.jsontrajectory_89.jsontrajectory_91.jsontrajectory_97.json
docs
FACTORING_PLAYBOOK.mdFALSE_POSITIVE_TEST_SUITE.mdOPERATOR_CERTIFICATES.mdROADMAP.mdSPECTRAL_ROUTE.md
experiment_contexts
exp_cebe1d9e7d8e.json
notebooks
spectral_history.ipynb
scripts
run_false_positive_tests.py
tests
run_false_positive_test_suite.pytest_cli.pytest_false_positive_methodology.pytest_false_positive_verifier.pytest_feedback_integration.pytest_partitioning.pytest_seed_management.pytest_self_opt_support.pytest_snapshot_system.pytest_spectral_paley.pytest_verification_robustness.py
tnfr_factorization
__init__.pyapi.pycli.pyfailure_telemetry.pyfeedback_adapter.pyfeedback_integration.pypartitioning.pyself_opt_support.pyspectral_paley.py
demo_snapshots.dbLICENSE_SNAPSHOT.mdPACKAGE_SUMMARY.mdREADME.mdseed_management.pysnapshot_system.pytest_certificate_hashing.pytest_installation.pyverification_trajectory_77.json
benchmarks
analyze_tetrad_universality.pyb0star_alpha_canonical_product_graphs.pybenchmark_optimization_tracks.pybenchmark_utils.pyboundary_vibration.pybridge_primes_riemann.pychiral_involution.pycli_utils.pycoherence_projector_sense_index.pycommutant_bridge.pycomposition_arithmetic.pyconfinement_zones_test.pyconservation_law_validation.pydirected_paley_bridge.pyemergent_arithmetic_pulse.pyemergent_atom_dynamics.pyemergent_atomic_shells.pyemergent_base_dimension.pyemergent_dimension_dynamics.pyemergent_fractal_pulse.pyemergent_fractal_simplex_dimension.pyemergent_integers_symmetry.pyemergent_musical_nfr.pyemergent_nfr_geometry.pyemergent_nfr_where.pyemergent_rationals.pyemergent_rhythm.pyemergent_screening.pyemergent_shell_cardinals.pyemergent_shell_ordering.pyemergent_simplex_dimension.pyemergent_substrate_symmetry.pyequivariance_wall.pyexternal_phase_gate_validation.pyfield_methods_battery.pygolden_residue_remesh_bridge.pyintegrated_force_regime_study.pyinverse_spectrum_to_symmetry.pyk_phi_safety_demo.pykuramoto_farey_bridge.pymissing_piece_bridge.pymultichannel_interface_benchmark.pynavier_stokes_recipe_bridge.pynodal_propagator_residue_bridge.pyns_moment_hierarchy_cascade.pyoperational_irreducibility.pypaley_bridge.pyphase_curvature_investigation.pyphase_wall.pyphi_s_confinement_investigation.pyprimes_as_consequence.pypulse_phase_coherence_budget.pyREADME.mdremesh_infinity_riemann_baseline.pyremesh_infinity_riemann_composed.pyremesh_infinity_riemann_modified_graph.pyremesh_infinity_riemann_operator.pyremesh_infinity_riemann_spectral_basis.pyremesh_infinity_riemann_spectral_robustness.pyremesh_infinity_riemann_spectral.pyresidue_phase_vs_riemann.pystructural_interface_benchmark.pytemporal_interface_benchmark.pytetrad_results_aggregate.pyu2_destabilization_irreversibility.pyuniversality_clusters.pyxi_c_fast_experiment.py
primality-test
benchmarks
comprehensive_benchmark.py
docs
ADVANCED_INTEGRATION.mdmathematical_foundation.mdperformance_analysis.md
examples
advanced_examples.pybasic_usage.py
tnfr_primality
__init__.py__main__.pyadvanced_cli.pyadvanced_core.pycli.pyconstants.pycore.pyoptimized.py
MANIFEST.inPACKAGE_SUMMARY.mdREADME.mdRELEASE_NOTES_v1.0.mdsetup.pytest_installation.py
tests
core_physics
__init__.pytest_conservation_laws.pytest_delta_nfr_computation_paths.pytest_delta_nfr.pytest_dispersion_coherence_sign_invariance.pytest_emergent_constants_guard.pytest_lyapunov_operators.pytest_nodal_equation.pytest_structural_triad.py
data
replay_manifests
sample_run
_manifest_summary.json_manifest.json_partition_files.txt.gz
self_opt_validation
seed_alpha
paley.json
seed_beta
integration.json
seed_gamma
unknown.json
self_optimization
test_run
partitioned
test_run
test_run_p0.jsontest_run_p1.json
_manifest_summary.json_manifest.json
engines
test_pattern_discovery_manifest.pytest_self_optimization_engine.py
mathematics
__init__.pytest_autodiff.pytest_backends.pytest_dissipative_dynamics.pytest_epi.pytest_factory_patterns.pytest_metrics.pytest_navier_stokes_refounded.pytest_number_theory_canonical.pytest_operators.pytest_residue_networks.pytest_riemann_nodal_pulse.pytest_riemann_pulse_coherence.pytest_spaces.pytest_transforms.pytest_validator.py
operators
test_canonical_operators_modern.pytest_grammar_canon.pytest_grammar_canonical_consistency.pytest_grammar_dynamics.pytest_operator_contracts.pytest_operator_strategies.py
parallel
test_fractal_partition_manifest.py
physics
test_conservation_gauge_unification.pytest_dissipative_conservation.pytest_emergent_chemistry.pytest_field_cache_invalidation.pytest_gauge.pytest_phase_transition.pytest_signatures.pytest_spectral_conservation.pytest_structural_diffusion.pytest_structural_integrity.pytest_symplectic_substrate.pytest_tetrad_bounds.pytest_variational.pytest_yang_mills_closure.pytest_yang_mills_derivability.pytest_yang_mills_scaling.pytest_yang_mills_structural_gap.pytest_yang_mills_u6_sweep.py
scripts
test_run_self_opt_validation.pytest_run_self_optimization.py
sdk
__init__.pytest_simple_advanced.py
__init__.pyconftest.pyREADME.mdtest_breast_cancer_phase_gate_demo.pytest_classical_mechanics.pytest_distributed_fft.pytest_external_phase_gate_validation.pytest_factorization_entrypoint.pytest_multichannel_interface.pytest_nodal_optimizer.pytest_phase_gate_api.pytest_replay_register_manifest.pytest_signal_confrontation.pytest_structural_interface_api.pytest_structural_interface_baselines.pytest_structural_interface_benchmark.pytest_temporal_interface.pytest_vectorized_coherence_length_regression.pytest_wine_quality_phase_gate_demo.pyutils.py
examples
01_foundations
01_hello_world.py02_musical_resonance.py03_network_formation.py04_operator_sequences.py05_coherence_evolution.py06_network_topologies.py07_phase_transitions.py08_emergent_phenomena.py09_visualization_suite.py10_simplified_sdk_showcase.py
02_physics_regimes
11_classical_limit_comparison.py115_operator_contract_audit.py12_classical_mechanics_demo.py13_quantum_mechanics_demo.py14_uncertainty_and_interference.py15_train_crossing_demo.py17_conservation_law_demo.py26_gauge_structure_demo.py27_variational_principle_demo.py28_dissipative_systems_demo.py29_lyapunov_stability_demo.py30_self_optimization_demo.py31_mathematical_constants_basis.py33_complex_field_unification.py34_conservation_protocol_suite.py35_tetrad_irreducibility.py36_grammar_violation_detector.py37_operator_tetrad_synergy.py38_grammar_energy_landscape.py39_nodal_equation_decomposition.py
03_riemann_zeta
157_nodal_pulse_phase_attack.py41_von_mangoldt_zeta_demo.py42_riemann_zeros_as_resonances.py43_prime_ladder_hamiltonian_demo.py44_weil_explicit_formula_demo.py45_li_keiper_demo.py46_weil_tnfr_positivity_demo.py47_alpha_sweep_demo.py48_admissible_family_sweep_demo.py49_nodeaware_gauge_sweep_demo.py50_uniform_coercivity_demo.py51_adaptive_coercivity_demo.py52_paley_gap_coercivity_demo.py53_lyapunov_spectral_positivity_demo.py54_hilbert_polya_demo.py55_structural_zero_density_demo.py56_spectral_emergence_demo.py57_admissible_rescaling_demo.py58_oscillatory_correction_demo.py
04_riemann_L_twisted
59_dirichlet_l_function_demo.py60_dirichlet_l_continuation_demo.py61_dirichlet_l_hamiltonian_demo.py62_dirichlet_weil_explicit_formula_demo.py63_dirichlet_li_keiper_demo.py64_twisted_weil_positivity_demo.py65_twisted_alpha_sweep_demo.py66_twisted_admissible_family_sweep_demo.py67_twisted_nodeaware_gauge_sweep_demo.py68_twisted_hermite_family_demo.py69_twisted_coercivity_uniform_demo.py70_twisted_paley_gap_coercivity_demo.py71_twisted_lyapunov_spectral_demo.py72_twisted_hilbert_polya_demo.py73_twisted_structural_zero_density_demo.py74_twisted_spectral_emergence_demo.py75_twisted_admissible_rescaling_demo.py76_twisted_oscillatory_correction_demo.py
05_type_hygiene
77_remesh_infinity_residue_split_demo.py78_nuf_type_signature_demo.py79_epi_type_signature_demo.py80_phi_type_signature_demo.py81_dnfr_type_signature_demo.py82_remesh_window_type_signature_demo.py83_delta_phi_max_type_signature_demo.py84_coupling_weights_type_signature_demo.py85_tetrad_closure_signature_demo.py86_currents_closure_signature_demo.py87_aggregates_closure_signature_demo.py88_urules_consistency_signature_demo.py89_operator_catalog_discipline_signature_demo.py
06_navier_stokes
158_navier_stokes_two_face_refounded.py
07_number_theory
100_prime_families_orbits.py101_numbers_as_coupled_network.py102_nodal_flow_primes_equilibria.py116_nuf_emergent_prime_visibility.py146_primality_grammatical_inertness.py147_numbers_as_free_monoid_words.py148_capacity_arm_carries_von_mangoldt.py149_p14_is_the_capacity_arm_operator.py153_structural_frequency_rank_cyclotomy.py40_arithmetic_number_theory.py94_generative_number_construction.py95_primes_from_spectral_waves.py96_spectral_vibration_of_coherence.py97_goldbach_additive_multiplicative.pyemergent_chemistry_particles_demo.py
08_emergent_geometry
103_emergent_substrate_meets_riemann.py106_per_node_polarization_geometry.py107_orthogonal_structure_emergent_geometry.py108_emergent_field_generating_structure.py112_structure_predicts_coherence_flow.py113_overdamped_projection_bridge.py114_substrate_conserved_quantities.py117_emergent_geometry_residue_graph.py118_emergent_vs_classical_operator.py119_phase_sector_directed_residue.py120_symmetry_wall_substrate_vs_spectrum.py121_canonical_symmetry_break_negative.py122_factorization_phase_sector.py123_symmetry_sector_decomposition.py124_emergent_metric_fractal_consistency.py125_node_is_the_emergent_substrate.py126_two_layers_base_fiber.py127_base_is_emergent_not_imposed.py128_base_substrate_coemergence.py129_spectral_gap_base_fiber_clock.py130_operators_break_substrate_charges.py131_coemergent_loop_convergence.py132_geometric_phase_holonomy.py133_psi_topological_defects.py134_spectral_dimension_heat_kernel.py135_arrow_of_time_h_theorem.py136_heat_kernel_coefficients.py137_synchronization_transition.py138_structure_frequency_synchronization.py139_grammar_formal_language.py140_grammar_automaton.py141_grammar_rule_decomposition.py142_grammar_operator_quotient.py143_glyphic_function_sublanguage.py144_branching_combinator.py145_syntactic_monoid_starfree.py150_emergent_grammatical_pattern_parry.py151_grammar_in_emergent_geometry.py152_operator_contract_tetrahedron.py154_conductor_annotated_qr_spectrum.py155_ontological_position_of_numbers.py156_emergence_directness_law.py98_emergent_symplectic_substrate.py99_structural_diffusion.pyunified_fields_showcase.py
09_millennium
109_p_vs_np_coherence_synthesis.py110_bsd_rank_structural_pressure.py111_hodge_discrete_and_honest_gap.py
10_applications
159_empirical_confrontation_pipeline.py90_phase_gate_monitor_demo.py91_breast_cancer_phase_gate_demo.py92_wine_quality_phase_gate_demo.py93_structural_interface_demo.pypytorch_cuda_demo.py
README.md
scripts
replay
__init__.pyregister_manifest.py
__init__.pyREADME.mdrebuild_failure_manifest.pyrun_reproducible_benchmarks.pyrun_self_opt_validation.pyrun_self_optimization.pytnfr_is_prime.pyvalidate_conservation_law.pyverify_internal_references.py
src
core
__init__.pyevaluation.py
tnfr
backends
__init__.pyjax_backend.pynumpy_backend.pyoptimized_numpy.pyREADME.mdtorch_backend.py
cli
__init__.py__init__.pyiarguments.pyarguments.pyiexecution.pyexecution.pyiinteractive_validator.pyREADME.mdutils.pyutils.pyi
compat
__init__.pydataclass.pyjsonschema_stub.pymatplotlib_stub.pynumpy_stub.pyREADME.md
config
__init__.py__init__.pyiconstants.pyconstants.pyidefaults_core.pydefaults_init.pydefaults_metric.pydefaults.pyfeature_flags.pyfeature_flags.pyiglyph_constants.pyoperator_names.pyoperator_names.pyiphysics_derivation.pyprecision_modes.pypresets.pypresets.pyiREADME.mdsecurity.pythresholds.pytnfr_config.py
constants
__init__.py__init__.pyialiases.pyaliases.pyicanonical.pymetric.pymetric.pyioperational.py
core
__init__.pycontainer.pydefault_implementations.pyexceptions.pyinterfaces.pyREADME.md
dynamics
__init__.py__init__.pyiadaptation.pyadaptation.pyiadaptive_sequences.pyadaptive_sequences.pyiadelic.pyadvanced_cache_optimizer.pyadvanced_fft_arithmetic.pyaliases.pyaliases.pyibifurcation.pycache_aware_fft_engine.pycanonical.pycanonical.pyicomputational_hub.pycoordination.pycoordination.pyidistributed_fft.pydnfr.pydnfr.pyidynamic_limits.pyemergent_centralization.pyemergent_integration_engine.pyfeedback.pyfeedback.pyifft_backend.pyfft_cache_coordinator.pyfft_dispatchers.pyfft_engine.pyfft_workers.pyfused_dnfr.pyhomeostasis.pyhomeostasis.pyiintegrators.pyintegrators.pyilearning.pylearning.pyimetabolism.pymulti_modal_cache.pynbody_tnfr.pynbody.pynodal_optimizer.pyoptimization_orchestrator.pypropagation.pyREADME.mdruntime.pyruntime.pyisampling.pysampling.pyiselectors.pyselectors.pyiself_optimizing_engine.pyspectral_structural_fusion.pystructural_cache.pystructural_clip.pysymplectic.pyunified_backend.pyunified_mathematical_cache_orchestrator.py
engines
computation
__init__.pyfft_engine.pyunified_fft_engine.pyunified_gpu_system.py
constants
__init__.pycanonical.pyoperational.py
integration
__init__.pyemergent_integration.py
pattern_discovery
__init__.pymathematical_patterns.pymulti_modal_cache.py
self_optimization
__init__.pyengine.py
__init__.pyREADME.md
errors
__init__.pycontextual.py
factorization
__init__.py
flatten
README.md
gamma
README.md
glyph_history
README.md
glyph_runtime
README.md
immutable
README.md
initialization
README.md
io
README.md
math
__init__.pyfields_symbolic.pygrammar_validators.pyoptimizer.pyREADME.mdsymbolic.py
mathematics
__init__.pybackend.pybackend.pyidynamics.pydynamics.pyiepi.pyepi.pyigenerators.pygenerators.pyiliouville.pymetrics.pymetrics.pyinumber_theory.pyoperators_factory.pyoperators_factory.pyioperators.pyoperators.pyioptimized_primality.pyprojection.pyprojection.pyiREADME.mdruntime.pyruntime.pyispaces.pyspaces.pyispectral.pytransforms.pytransforms.pyiunified_cache.pyunified_numerical.pyzeta.py
metrics
__init__.py__init__.pyibuffer_cache.pybuffer_cache.pyicache_utils.pycoherence.pycoherence.pyicommon.pycommon.pyicore.pycore.pyidiagnosis.pydiagnosis.pyiemergence.pyexport.pyexport.pyiglyph_timing.pyglyph_timing.pyilearning_metrics.pylearning_metrics.pyilocal_coherence.pyphase_coherence.pyphase_compatibility.pyREADME.mdreporting.pyreporting.pyisense_index.pysense_index.pyitelemetry.pytetrad.pytrig_cache.pytrig_cache.pyitrig.pytrig.pyi
multiscale
__init__.pyhierarchical.pyREADME.md
navier_stokes
__init__.pyconservative_face.pyoperator.py
node
README.md
observers
README.md
operators
network_analysis
__init__.pysource_detection.py
postconditions
__init__.pymutation.py
preconditions
__init__.pycoherence.pydissonance.pyemission.pymutation.pyreception.pyresonance.py
strategies
__init__.pydefaults.pygpu_strategies.pystrategy.py
__init__.py__init__.pyialgebra.pycanonical_patterns.pycascade.pycoherence.pycontraction.pycoupling.pycycle_detection.pydefinitions_base.pydefinitions.pydefinitions.pyidissonance.pyemission.pyexpansion.pygrammar_application.pygrammar_canon.pygrammar_context.pygrammar_core.pygrammar_dynamics.pygrammar_error_factory.pygrammar_memoization.pygrammar_patterns.pygrammar_telemetry.pygrammar_types.pygrammar_u6.pygrammar_validate.pygrammar.pygrammar.pyihamiltonian.pyhealth_analyzer.pyintrospection.pyjitter.pyjitter.pyilifecycle.pymetabolism.pymetrics_basic.pymetrics_core.pymetrics_network.pymetrics_structural.pymetrics_u6.pymetrics.pymutation.pynodal_equation.pyoperator_contracts.pypattern_detection.pypatterns.pyREADME.mdreception.pyrecursivity.pyregistry.pyregistry.pyiremesh.pyremesh.pyiresonance.pyself_organization.pysilence.pystructural_units.pytransition.py
parallel
__init__.pyauto_scaler.pydistributed.pyengine.pymonitoring.pypartitioner.pyREADME.md
performance
guardrails.py
physics
__init__.py_helpers.pycalibration.pycanonical.pycell.pyclassical_mechanics.pyconservation_gauge_unification.pyconservation.pydissipative_conservation.pyemergent_chemistry.pyemergent_particles.pyextended.pyfields.pygauge.pyintegrity.pyinteractions.pylife.pylyapunov.pypatterns.pyphase_transition.pyquantum_mechanics.pyREADME.mdsignatures.pyspectral_conservation.pyspectral_metrics.pystructural_diffusion.pysymplectic_substrate.pytelemetry.pyunified.pyvariational.pyvectorized_ops.py
primality
__init__.py
recipes
__init__.pycookbook.pyREADME.md
riemann
__init__.pyadmissible_family_sweep.pyadmissible_rescaling.pyaggregates_closure_signature.pyalpha_sweep.pyanalytic_continuation_dirichlet.pyanalytic_continuation.pycoercivity_uniform.pycoupling_weights_type_signature.pycurrents_closure_signature.pydelta_phi_max_type_signature.pydirichlet_l.pydnfr_type_signature.pyepi_type_signature.pyhilbert_polya.pyli_keiper.pylyapunov_spectral_positivity.pynodal_pulse.pynodeaware_gauge_sweep.pynuf_type_signature.pyoperator_catalog_discipline_signature.pyoperator.pyoscillatory_correction.pypaley_gap_coercivity.pyphi_type_signature.pyprime_ladder_hamiltonian.pypulse_coherence.pyremesh_infinity_residue_split.pyremesh_window_type_signature.pyspectral_emergence.pystructural_zero_density.pytelemetry.pytetrad_closure_signature.pytwisted_admissible_family_sweep.pytwisted_admissible_rescaling.pytwisted_alpha_sweep.pytwisted_coercivity_uniform.pytwisted_hermite_family.pytwisted_hilbert_polya.pytwisted_li_keiper.pytwisted_lyapunov_spectral_positivity.pytwisted_nodeaware_gauge_sweep.pytwisted_oscillatory_correction.pytwisted_paley_gap_coercivity.pytwisted_prime_ladder_hamiltonian.pytwisted_spectral_emergence.pytwisted_structural_zero_density.pytwisted_weil_explicit_formula.pytwisted_weil_positivity.pyurules_consistency_signature.pyvon_mangoldt.pyweil_explicit_formula.pyweil_positivity.py
schemas
__init__.pygrammar.jsonREADME.md
sdk
__init__.py__init__.pyiadaptive_system.pyadaptive_system.pyibuilders.pybuilders.pyifluent.pyfluent.pyiREADME.mdself_opt.pysimple.pytemplates.pytemplates.pyiutils.py
security
__init__.pycrypto.pydatabase.pyREADME.mdsubprocess.pyvalidation.py
sequencing
__init__.pypatterns.pyREADME.md
services
__init__.pyorchestrator.pyREADME.md
sparse
__init__.pyREADME.mdrepresentations.py
structural
README.md
telemetry
__init__.pycache_metrics.pycache_metrics.pyiconstants.pynu_f.pynu_f.pyiREADME.mdunified_telemetry_system.pyverbosity.pyverbosity.pyi
tools
__init__.pydomain_templates.pyREADME.mdsequence_generator.pytnfr_is_prime_cli_optimized.pytnfr_is_prime_cli.py
topology
__init__.pyasymmetry.pyREADME.md
utils
cache_layers.pycache.pycache.pyicallbacks.pycallbacks.pyichunks.pychunks.pyidata.pydata.pyifast_diameter.pygraph.pygraph.pyiinit.pyinit.pyiio.pyio.pyinumeric.pynumeric.pyiREADME.mdtopology.pyunified_cache.py
validation
__init__.py__init__.pyiaggregator.pybase.pycompatibility.pycompatibility.pyiconfig.pygraph.pygraph.pyihealth.pyinput_validation.pyinterface_baselines.pyinvariants.pymultichannel_interface.pyphase_gate.pyREADME.mdrules.pyrules.pyiruntime.pyruntime.pyisequence_validator.pysignal_confrontation.pysoft_filters.pysoft_filters.pyispectral.pyspectral.pyistructural_interface.pytemporal_interface.pyunified_validation_system.pyvalidator.pywindow.pywindow.pyi
visualization
__init__.pycascade_viz.pyhierarchy.pyREADME.mdsequence_plotter.py
yang_mills
__init__.pyclosure.pyderivability.pyscaling.pystructural_gap.pyu6_sweep.py
__init__.py__init__.pyi_compat.py_version.py_version.pyialias.pyalias.pyibackend_config.pycache.pycache.pyiexecution.pyexecution.pyiflatten.pyflatten.pyigamma.pygamma.pyiglyph_history.pyglyph_history.pyiglyph_runtime.pyglyph_runtime.pyiimmutable.pyimmutable.pyiinitialization.pyinitialization.pyiio.pyio.pyilocking.pylocking.pyinode.pynode.pyiobservers.pyobservers.pyiontosim.pyontosim.pyipy.typedrng.pyrng.pyisecure_config.pyselector.pyselector.pyisense.pysense.pyistructural.pystructural.pyitokens.pytokens.pyitrace.pytrace.pyitypes.pytypes.pyiunits.pyunits.pyi
tetrad_evaluator.py
.pre-commit-config.yaml.semgrep.yaml.zenodo.jsonARCHITECTURE.mdbandit.yamlCHANGELOG.mdCITATION.cffCONTRIBUTING.mdEMERGENT_CANON_AUDIT.mdEMERGENT_DERIVATION_PLAN.mdLICENSE.mdMakefileMANIFEST.inpyproject.tomlpyrightconfig.jsonPYTORCH_CUDA_INTEGRATION.mdREADME.mdSECURITY.mdTESTING.mdTNFR_Website_Content_Brief.md
FILE: src/tnfr/physics/lyapunov.py

lyapunov.py

Source Code

python
r"""Formal Lyapunov stability analysis for all 13 canonical operators.

This module extends the generic Lyapunov analysis in ``conservation.py``
with **per-operator energy bounds** derived from the glyph factors defined
in ``tnfr.config.defaults_core.GLYPH_FACTORS`` and the canonical constants
in ``tnfr.constants.canonical``.

Physics Foundation
------------------
The structural Lyapunov functional is **emergent**, not imposed.  It is the
coherence the operators natively alter, which has two equivalent emergent forms:

- the **coherence** ``C(t) = 1/(1 + mean|ΔNFR| + mean|dEPI|)``, emerging directly
  from the nodal dynamics ``∂EPI/∂t = νf·ΔNFR``; and
- the **tetrad energy** ``E = ½ Σ_i [Φ_s² + |∇φ|² + K_φ² + J_φ² + J_ΔNFR²]``
  (conservation.py), which emerges purely from the tetrad geometry — Φ_s and
  J_ΔNFR from the structural pressure ΔNFR, and |∇φ|/K_φ/J_φ from the phase θ.
  E contains **no EPI or νf term** (measured: scaling EPI or νf leaves E
  unchanged); both functionals share the structural-pressure channel |ΔNFR|.

Each operator changes the coherence by a bounded amount whose sign is its
canonical grammar role, DERIVED from ``config.physics_derivation`` (the single
source of truth, identical to the grammar U2 classification):

- **Stabilisers** (IL, THOL): reduce |ΔNFR| → raise coherence (Lyapunov-
  contractive), with a contraction rate from the operator's pressure factor.
- **Destabilisers** (OZ, ZHIR, VAL): raise |ΔNFR| → lower coherence, with an
  explicit expansion rate.
- **Neutral** (AL, EN, RA, UM, SHA, NUL, NAV, REMESH): act on the EPI-form,
  νf-capacity, θ-phase or advisory channel that the coherence-pressure functional
  does not penalise by its grammatical role — so they neither contract nor expand
  coherence (|ΔE_coherence| ≈ 0 by their U2 role).

Grammar rule U2 (CONVERGENCE & BOUNDEDNESS) requires that every
destabiliser be accompanied by a stabiliser.  The derivation argues that
the *net* coherence change across a grammar-compliant sequence is
non-negative (energy non-positive), supporting the Lyapunov proposition.
A complete formal proof of asymptotic stability remains open (see §8.2 of
the theory document for the proof sketch and its limitations).

Spectral Gap Characterisation
-----------------------------
``analyze_spectral_gap`` reports two distinct, both-meaningful quantities:

- the **combinatorial algebraic connectivity** λ₁ (Fiedler value) of
  L = D − A — a graph-topology measure; and
- the **canonical diffusion relaxation gap** λ₂ of the symmetric normalized
  Laplacian L_sym = I − D^{-1/2} W D^{-1/2}, which shares the spectrum of the
  canonical TNFR diffusion operator L_rw = I − D⁻¹W (``structural_diffusion``).

The *diffusive* relaxation time-scale is set by the **diffusion gap**: the EPI
field relaxes as exp(−ν_f·λ₂·t).  The two gaps coincide only up to the degree
normalisation (λ₁/d on a d-regular graph) and differ on irregular graphs.
Derived: relaxation time, mixing-time estimate, Cheeger-type bound, and the
stabiliser convergence rate (which uses the canonical diffusion gap).

References
----------
- AGENTS.md §Structural Conservation Theorem
- theory/STRUCTURAL_CONSERVATION_THEOREM.md §8 Lyapunov Stability
- src/tnfr/physics/conservation.py (LyapunovResult, SpectralConservation)
"""

from __future__ import annotations

import math
from dataclasses import dataclass
from enum import Enum
from typing import Any, Sequence

try:
    import numpy as np
except ImportError:  # pragma: no cover
    np = None  # type: ignore[assignment]

try:
    import networkx as nx
except ImportError:  # pragma: no cover
    nx = None  # type: ignore[assignment]

# Lazy import to break circular dependencies
_conservation = None


def _get_conservation():
    global _conservation
    if _conservation is None:
        from tnfr.physics import conservation as _mod

        _conservation = _mod
    return _conservation


# ---------------------------------------------------------------------------
#  Canonical glyph factors (defaults from tnfr.config.defaults_core)
# ---------------------------------------------------------------------------

# Import canonical constants for single-source-of-truth
from tnfr.constants.canonical import AL_BOOST_CANONICAL, EN_MIX_FACTOR, NUL_DENSIFICATION_FACTOR, NUL_SCALE_FACTOR, SHA_VF_FACTOR, UM_THETA_PUSH, VAL_SCALE_FACTOR

# Values documented in AGENTS.md § The 13 Canonical Operators
_GLYPH_DEFAULTS: dict[str, float] = {
    "AL_boost": 0.10,  # Emission EPI increment (free gain; energy-neutral)
    "EN_mix": EN_MIX_FACTOR,  # 1/(π+1) ≈ 0.2415
    "IL_dnfr_factor": 0.75,  # Coherence |ΔNFR| retention (stabiliser)
    "OZ_dnfr_factor": 2.0,  # Dissonance |ΔNFR| amplification (destabiliser)
    "UM_theta_push": UM_THETA_PUSH,  # 1/(π+1) ≈ 0.2415
    "UM_vf_sync": 0.10,
    "UM_dnfr_reduction": 0.15,
    "RA_epi_diff": 0.15,
    "RA_vf_amplification": 0.05,
    "RA_phase_coupling": 0.10,
    "SHA_vf_factor": round(SHA_VF_FACTOR, 4),  # 0.9 (ν_f freeze step)
    "VAL_scale": round(VAL_SCALE_FACTOR, 4),  # 1.05 (ν_f expansion step)
    "NUL_scale": round(NUL_SCALE_FACTOR, 4),  # 0.9 (ν_f contraction step)
    "NUL_densification_factor": round(NUL_DENSIFICATION_FACTOR, 4),  # 1/λ ≈ 1.111
    "THOL_accel": 0.10,
    "ZHIR_theta_shift_factor": 0.3,
    "NAV_eta": 0.5,
    "NAV_jitter": 0.05,
    "REMESH_alpha": 0.5,
}

# ---------------------------------------------------------------------------
#  Energy class taxonomy
# ---------------------------------------------------------------------------


class EnergyClass(str, Enum):
    """Classification of an operator's effect on the energy functional."""

    STABILISER = "stabiliser"  # dE/dt ≤ 0 (contractive)
    DESTABILISER = "destabiliser"  # dE/dt > 0 (expansive, bounded)
    NEUTRAL = "neutral"  # |dE/dt| ≈ 0 (quasi-isometric)
    MIXED = "mixed"  # sign depends on state


# ---------------------------------------------------------------------------
#  Per-operator Lyapunov bound
# ---------------------------------------------------------------------------


@dataclass(frozen=True)
class OperatorLyapunovBound:
    r"""Formal energy bound for a single canonical operator application.

    Each operator O maps E → E + ΔE where:
    - Stabilisers:   ΔE ≤ -ρ · E  for some contraction rate ρ > 0
    - Destabilisers: ΔE ≤ +κ · E  for some expansion rate κ > 0
    - Neutral:       |ΔE| ≤ ε      for some small residual ε ≥ 0
    - Mixed:         ΔE ≤ +κ · E   (worst case as destabiliser)

    The net energy change across a grammar-compliant sequence satisfies
    ΔE_net ≤ E₀ · Π(1 + cᵢ) - E₀ where cᵢ < 0 for stabilisers and
    cᵢ > 0 for destabilisers.  U2 guarantees Σ cᵢ ≤ 0.

    Attributes
    ----------
    operator_name : str
        Canonical operator name (e.g. ``"Coherence"``).
    glyph : str
        Two-to-five letter glyph (e.g. ``"IL"``).
    energy_class : EnergyClass
        Stabiliser / destabiliser / neutral / mixed.
    contraction_rate : float
        ρ > 0 for stabilisers (fractional energy decrease per step).
        For destabilisers this is the expansion rate κ.
        For neutral operators this is the residual bound ε.
    glyph_factor_name : str
        Name of the dominant glyph factor (e.g. ``"IL_dnfr_factor"``).
    glyph_factor_value : float
        Numeric value of the glyph factor.
    derivation : str
        Human-readable derivation sketch of the bound.
    """

    operator_name: str
    glyph: str
    energy_class: EnergyClass
    contraction_rate: float
    glyph_factor_name: str
    glyph_factor_value: float
    derivation: str


# ---------------------------------------------------------------------------
#  Registry of formal bounds for all 13 operators
# ---------------------------------------------------------------------------


def _build_bounds() -> dict[str, OperatorLyapunovBound]:
    """Construct the canonical Lyapunov bounds dictionary.

    Each bound is derived from the operator's ``apply()`` semantics and its
    dominant glyph factor, as documented in ``AGENTS.md``.
    """
    gf = _GLYPH_DEFAULTS

    # ── CANONICAL CLASSIFICATION — single source of truth ───────────────────
    #
    # The structural Lyapunov functional is EMERGENT, not a pre-existing
    # scoreboard: the tetrad energy E = ½Σ(Φ_s² + |∇φ|² + K_φ² + J_φ² + J_ΔNFR²)
    # (conservation.py) emerges from the phase field θ and the structural
    # pressure ΔNFR — Φ_s and J_ΔNFR come from ΔNFR, |∇φ|/K_φ/J_φ from θ.  It
    # contains NO EPI or νf term (measured: scaling EPI or νf leaves E exactly
    # unchanged).  Equivalently, the primary coherence
    # C(t) = 1/(1 + mean|ΔNFR| + mean|dEPI|) emerges from the nodal dynamics
    # ∂EPI/∂t = νf·ΔNFR.  What operators NATIVELY alter is the coherence,
    # through the structural-pressure channel |ΔNFR|.
    #
    # The per-operator Lyapunov role is therefore the canonical grammar
    # coherence-pressure role, DERIVED from the nodal-equation predicates in
    # ``config.physics_derivation`` (the SAME single source of truth the grammar
    # U2 sets derive from) — NOT from hardcoded energy algebra that wrongly
    # assumed EPI/νf entered E:
    #   provides_negative_feedback(op)   → STABILISER (reduces |ΔNFR| → raises C)
    #   increases_structural_pressure(op)→ DESTABILISER (raises |ΔNFR| → lowers C)
    #   otherwise                        → NEUTRAL  (acts on the EPI-form,
    #       νf-capacity, θ-phase or advisory channel that the coherence-pressure
    #       functional does not penalise by its grammatical role).
    from ..config.operator_names import (
        COHERENCE,
        CONTRACTION,
        COUPLING,
        DISSONANCE,
        EMISSION,
        EXPANSION,
        MUTATION,
        RECEPTION,
        RECURSIVITY,
        RESONANCE,
        SELF_ORGANIZATION,
        SILENCE,
        TRANSITION,
    )
    from ..config.physics_derivation import (
        increases_structural_pressure,
        provides_negative_feedback,
    )
    from ..operators.operator_contracts import contract_for

    # (function name, dominant structural-pressure factor). The English name
    # and glyph are NOT duplicated here — they derive from the canonical
    # operator_contracts single source via contract_for() below.
    _OPS = (
        (EMISSION, "AL_boost"),
        (RECEPTION, "EN_mix"),
        (COHERENCE, "IL_dnfr_factor"),
        (DISSONANCE, "OZ_dnfr_factor"),
        (COUPLING, "UM_dnfr_reduction"),
        (RESONANCE, "RA_vf_amplification"),
        (SILENCE, "SHA_vf_factor"),
        (EXPANSION, "VAL_scale"),
        (CONTRACTION, "NUL_scale"),
        (SELF_ORGANIZATION, "THOL_accel"),
        (MUTATION, "ZHIR_theta_shift_factor"),
        (TRANSITION, "NAV_eta"),
        (RECURSIVITY, "REMESH_alpha"),
    )

    bounds: dict[str, OperatorLyapunovBound] = {}
    for fname, factor_name in _OPS:
        contract = contract_for(fname)
        ename = contract.english_name
        glyph = contract.glyph
        factor_val = float(gf.get(factor_name, 0.0))
        if provides_negative_feedback(fname):
            energy_class = EnergyClass.STABILISER
            if fname == COHERENCE:
                # IL scales |ΔNFR| → f·|ΔNFR| (f<1); pressure contraction = 1−f.
                rate = max(0.0, 1.0 - factor_val)
                deriv = (
                    f"IL reduces structural pressure |ΔNFR| → f·|ΔNFR| "
                    f"(f={factor_val:.3f}); coherence C=1/(1+mean|ΔNFR|+…) "
                    f"rises. Pressure contraction ρ = 1−f ≈ {rate:.3f}."
                )
            else:  # THOL
                # THOL redistributes |ΔNFR| into coherent sub-EPIs (handler).
                rate = factor_val
                deriv = (
                    f"THOL redistributes |ΔNFR| into coherent sub-EPIs "
                    f"(accel={factor_val:.3f}); the negative feedback raises "
                    f"coherence. Redistribution ρ ≈ {rate:.3f}."
                )
        elif increases_structural_pressure(fname):
            energy_class = EnergyClass.DESTABILISER
            if fname == DISSONANCE:
                # OZ scales |ΔNFR| → f·|ΔNFR| (f>1); pressure expansion = f−1.
                rate = max(0.0, factor_val - 1.0)
                deriv = (
                    f"OZ raises structural pressure |ΔNFR| → f·|ΔNFR| "
                    f"(f={factor_val:.3f}); coherence falls. Pressure "
                    f"expansion κ = f−1 ≈ {rate:.3f}."
                )
            elif fname == EXPANSION:
                # VAL adds unaligned DOF (scales νf); the new DOF raise |ΔNFR|.
                rate = max(0.0, factor_val - 1.0)
                deriv = (
                    f"VAL adds unaligned structural DOF (νf scale "
                    f"{factor_val:.3f}); the new DOF raise |ΔNFR| → coherence "
                    f"falls. Nominal expansion κ ≈ {rate:.3f}."
                )
            else:  # ZHIR
                # ZHIR's θ→θ' jump desynchronises the node → raises |∇φ| and
                # hence the structural pressure |ΔNFR|.
                rate = factor_val
                deriv = (
                    f"ZHIR jumps θ→θ' (shift factor {factor_val:.3f}); the "
                    f"phase desync raises |∇φ| → raises |ΔNFR| → coherence "
                    f"falls. Nominal expansion κ ≈ {rate:.3f}."
                )
        else:
            energy_class = EnergyClass.NEUTRAL
            rate = 0.0
            deriv = (
                "Coherence-neutral by grammatical role: acts on the EPI-form "
                "(AL/EN/RA), νf-capacity (SHA/NUL), θ-phase (UM) or advisory "
                "(NAV/REMESH) channel, not the structural-pressure |ΔNFR| axis "
                "the coherence functional penalises — so it neither contracts "
                "nor expands coherence by its U2 role."
            )
        bounds[ename] = OperatorLyapunovBound(
            operator_name=ename,
            glyph=glyph,
            energy_class=energy_class,
            contraction_rate=rate,
            glyph_factor_name=factor_name,
            glyph_factor_value=factor_val,
            derivation=deriv,
        )

    return bounds


# Singleton registry
OPERATOR_LYAPUNOV_BOUNDS: dict[str, OperatorLyapunovBound] = _build_bounds()

# Glyph → name lookup
_GLYPH_TO_NAME: dict[str, str] = {
    b.glyph: b.operator_name for b in OPERATOR_LYAPUNOV_BOUNDS.values()
}


def get_bound(name_or_glyph: str) -> OperatorLyapunovBound:
    """Look up the formal Lyapunov bound by operator name or glyph.

    Parameters
    ----------
    name_or_glyph : str
        Either the full name (e.g. ``"Coherence"``) or the glyph
        (e.g. ``"IL"``).

    Returns
    -------
    OperatorLyapunovBound

    Raises
    ------
    KeyError
        If the name/glyph is not recognised.
    """
    if name_or_glyph in OPERATOR_LYAPUNOV_BOUNDS:
        return OPERATOR_LYAPUNOV_BOUNDS[name_or_glyph]
    if name_or_glyph in _GLYPH_TO_NAME:
        return OPERATOR_LYAPUNOV_BOUNDS[_GLYPH_TO_NAME[name_or_glyph]]
    raise KeyError(
        f"Unknown operator {name_or_glyph!r}.  "
        f"Valid names: {sorted(OPERATOR_LYAPUNOV_BOUNDS)}"
    )


# ---------------------------------------------------------------------------
#  Per-operator energy bound computation
# ---------------------------------------------------------------------------


def compute_operator_energy_bound(
    name_or_glyph: str,
    energy_before: float,
    n_nodes: int = 1,
) -> float:
    r"""Return the theoretical upper bound on ΔE for one operator step.

    Parameters
    ----------
    name_or_glyph : str
        Operator name or glyph.
    energy_before : float
        E[G] before operator application.
    n_nodes : int
        Number of nodes affected (default 1 for single-node operators).

    Returns
    -------
    float
        Upper bound on E_after - E_before.
        Negative for stabilisers (guaranteed decrease).
        Positive for destabilisers (worst-case increase).
    """
    bound = get_bound(name_or_glyph)
    rate = bound.contraction_rate

    if bound.energy_class == EnergyClass.STABILISER:
        # Guaranteed decrease: ΔE ≤ -ρ · E (where ρ > 0)
        return -rate * energy_before

    if bound.energy_class == EnergyClass.DESTABILISER:
        # Worst-case increase: ΔE ≤ κ · E (for multiplicative)
        # For additive (AL): ΔE ≤ κ · N  (κ = boost²)
        if bound.glyph == "AL":
            return rate * n_nodes
        return rate * energy_before

    if bound.energy_class == EnergyClass.NEUTRAL:
        # Residual bound: |ΔE| ≤ ε · N
        return rate * n_nodes

    # MIXED (NUL): worst-case as destabiliser
    return rate * energy_before


# ---------------------------------------------------------------------------
#  Sequence energy bound (grammar-compliant U2)
# ---------------------------------------------------------------------------


def compute_sequence_energy_bound(
    operator_names: Sequence[str],
    energy_initial: float,
    n_nodes: int = 1,
) -> float:
    r"""Compute theoretical upper bound on energy after full sequence.

    Under grammar rule U2, every destabiliser must be compensated by
    a stabiliser.  This function computes the cumulative energy bound
    assuming worst-case ordering per step.

    Parameters
    ----------
    operator_names : Sequence[str]
        Ordered operator names or glyphs.
    energy_initial : float
        Starting energy E₀.
    n_nodes : int
        Network size.

    Returns
    -------
    float
        Upper bound on final energy E_final.
    """
    e = energy_initial
    for name in operator_names:
        delta = compute_operator_energy_bound(name, e, n_nodes)
        e = e + delta
        # Energy cannot go below zero
        e = max(0.0, e)
    return e


# ---------------------------------------------------------------------------
#  Operator Lyapunov verification (empirical check)
# ---------------------------------------------------------------------------


@dataclass(frozen=True)
class OperatorLyapunovVerification:
    r"""Result of verifying an operator's energy change against its bound.

    Attributes
    ----------
    operator_name : str
    glyph : str
    energy_before : float
    energy_after : float
    delta_e : float
        Actual E_after - E_before.
    theoretical_bound : float
        Upper bound on ΔE from formal analysis.
    within_bound : bool
        True if delta_e ≤ theoretical_bound + tolerance.
    margin : float
        theoretical_bound - delta_e (positive = safe margin).
    energy_class : EnergyClass
    """

    operator_name: str
    glyph: str
    energy_before: float
    energy_after: float
    delta_e: float
    theoretical_bound: float
    within_bound: bool
    margin: float
    energy_class: EnergyClass


def verify_operator_lyapunov(
    name_or_glyph: str,
    energy_before: float,
    energy_after: float,
    n_nodes: int = 1,
    tolerance: float = 1e-6,
) -> OperatorLyapunovVerification:
    r"""Verify that an operator's actual energy change respects its bound.

    Parameters
    ----------
    name_or_glyph : str
        Operator name or glyph.
    energy_before, energy_after : float
        Measured energy functional values.
    n_nodes : int
        Number of affected nodes.
    tolerance : float
        Numerical tolerance for bound check.

    Returns
    -------
    OperatorLyapunovVerification
    """
    bound_info = get_bound(name_or_glyph)
    delta_e = energy_after - energy_before
    theoretical = compute_operator_energy_bound(name_or_glyph, energy_before, n_nodes)
    margin = theoretical - delta_e

    return OperatorLyapunovVerification(
        operator_name=bound_info.operator_name,
        glyph=bound_info.glyph,
        energy_before=energy_before,
        energy_after=energy_after,
        delta_e=delta_e,
        theoretical_bound=theoretical,
        within_bound=(delta_e <= theoretical + tolerance),
        margin=margin,
        energy_class=bound_info.energy_class,
    )


# ---------------------------------------------------------------------------
#  Spectral gap analysis
# ---------------------------------------------------------------------------


@dataclass(frozen=True)
class SpectralGapAnalysis:
    r"""Comprehensive spectral gap characterisation of a TNFR network.

    The algebraic connectivity λ₁ (smallest non-zero Laplacian eigenvalue)
    controls the diffusive relaxation time-scale.

    Attributes
    ----------
    spectral_gap : float
        λ₁ — combinatorial algebraic connectivity (Fiedler value): the
        second-smallest eigenvalue of L = D − A.  A graph-topology measure.
    fiedler_value : float
        Same as spectral_gap (alternative name from spectral graph theory).
    diffusion_gap : float
        λ₂ of the symmetric normalized Laplacian L_sym = I − D^{-1/2} W D^{-1/2},
        which shares the spectrum of the canonical TNFR diffusion operator
        L_rw = I − D⁻¹W.  This is the **canonical structural relaxation rate**
        (per unit ν_f): the EPI field relaxes as exp(−ν_f·λ₂·t).  Use this — not
        the combinatorial ``spectral_gap`` — for the diffusive relaxation
        time-scale.  Equals ``spectral_gap``/d on a d-regular graph; differs on
        irregular graphs.
    relaxation_time : float
        τ_relax = 1/λ₁ — time for the slowest non-trivial mode to decay
        by factor e.  ``inf`` if graph is disconnected (λ₁ = 0).
    convergence_rate : float
        Exponential convergence rate for diffusive processes: exp(-λ₁ t).
    mixing_time_bound : float
        Upper bound on mixing time: t_mix ≤ ln(N)/λ₁.
    cheeger_lower : float
        Cheeger inequality lower bound: h²/(2·d_max) ≤ λ₁.
        Stored as h_estimate = √(2·d_max·λ₁).
    n_nodes : int
        Network size.
    max_eigenvalue : float
        Largest Laplacian eigenvalue λ_max.
    spectral_ratio : float
        λ_max / λ₁ — condition number of the non-trivial spectrum.
        Lower is better-connected.
    is_connected : bool
        True if λ₁ > 0 (graph is connected).
    eigenvalues : Any
        Full Laplacian spectrum (np.ndarray).
    """

    spectral_gap: float
    fiedler_value: float
    diffusion_gap: float
    relaxation_time: float
    convergence_rate: float
    mixing_time_bound: float
    cheeger_lower: float
    n_nodes: int
    max_eigenvalue: float
    spectral_ratio: float
    is_connected: bool
    eigenvalues: Any  # np.ndarray


def analyze_spectral_gap(G: Any) -> SpectralGapAnalysis:
    r"""Compute the spectral gap and derived quantities for a TNFR graph.

    Forms the graph Laplacian L, computes its eigenvalues, and derives:
    - λ₁ (algebraic connectivity / Fiedler value)
    - Relaxation time τ = 1/λ₁
    - Mixing time bound ln(N)/λ₁
    - Cheeger estimate h ≈ √(2·d_max·λ₁)
    - Spectral condition ratio λ_max/λ₁

    Parameters
    ----------
    G : networkx.Graph
        The TNFR network.

    Returns
    -------
    SpectralGapAnalysis
    """
    if np is None:
        raise ImportError("numpy is required for spectral gap analysis")

    n = G.number_of_nodes()
    if n < 2:
        return SpectralGapAnalysis(
            spectral_gap=0.0,
            fiedler_value=0.0,
            diffusion_gap=0.0,
            relaxation_time=float("inf"),
            convergence_rate=0.0,
            mixing_time_bound=float("inf"),
            cheeger_lower=0.0,
            n_nodes=n,
            max_eigenvalue=0.0,
            spectral_ratio=float("inf"),
            is_connected=(n == 1),
            eigenvalues=np.array([0.0]) if n == 1 else np.array([]),
        )

    # Build Laplacian
    if nx is not None and isinstance(G, nx.Graph):
        L = nx.laplacian_matrix(G).toarray().astype(float)
    else:
        nodes = sorted(G.nodes())
        node_idx = {nd: i for i, nd in enumerate(nodes)}
        L = np.zeros((n, n))
        for u, v in G.edges():
            i, j = node_idx[u], node_idx[v]
            L[i, j] = -1.0
            L[j, i] = -1.0
            L[i, i] += 1.0
            L[j, j] += 1.0

    eigvals = np.linalg.eigvalsh(L)
    eigvals = np.sort(eigvals)

    # λ₁ = second-smallest eigenvalue (combinatorial algebraic connectivity)
    lambda_1 = float(eigvals[1]) if n > 1 else 0.0
    lambda_1 = max(0.0, lambda_1)  # numerical safety

    lambda_max = float(eigvals[-1])

    # Canonical structural relaxation rate: λ₂ of the symmetric normalized
    # Laplacian L_sym (shares the spectrum of the canonical diffusion operator
    # L_rw = I − D⁻¹W; built once in structural_diffusion).
    from .structural_diffusion import symmetric_normalized_laplacian

    _, L_sym = symmetric_normalized_laplacian(G)
    sym_eigs = np.sort(np.linalg.eigvalsh(L_sym))
    diffusion_gap = max(0.0, float(sym_eigs[1])) if n > 1 else 0.0

    is_connected = lambda_1 > 1e-10
    tau = 1.0 / lambda_1 if is_connected else float("inf")
    mixing = math.log(n) / lambda_1 if is_connected else float("inf")

    # Maximum degree for Cheeger bound
    d_max = max(dict(G.degree()).values()) if n > 0 else 1
    cheeger_h = math.sqrt(2.0 * d_max * lambda_1) if is_connected else 0.0

    ratio = lambda_max / lambda_1 if is_connected else float("inf")

    return SpectralGapAnalysis(
        spectral_gap=lambda_1,
        fiedler_value=lambda_1,
        diffusion_gap=diffusion_gap,
        relaxation_time=tau,
        convergence_rate=lambda_1,
        mixing_time_bound=mixing,
        cheeger_lower=cheeger_h,
        n_nodes=n,
        max_eigenvalue=lambda_max,
        spectral_ratio=ratio,
        is_connected=is_connected,
        eigenvalues=eigvals,
    )


# ---------------------------------------------------------------------------
#  Combined Lyapunov + spectral convergence analysis
# ---------------------------------------------------------------------------


@dataclass(frozen=True)
class LyapunovSpectralSummary:
    r"""Combined per-operator Lyapunov + spectral gap summary.

    Attributes
    ----------
    operator_bound : OperatorLyapunovBound
        Formal energy bound for the operator.
    spectral : SpectralGapAnalysis
        Spectral gap analysis of the graph.
    effective_convergence_rate : float
        For stabilisers: min(ρ, λ₁) — the tighter of the operator's
        contraction rate and the graph's spectral relaxation.
        For destabilisers/neutral: 0.0.
    steps_to_half_energy : float
        For stabilisers: ln(2) / effective_convergence_rate.
        Number of steps to halve the energy.
    """

    operator_bound: OperatorLyapunovBound
    spectral: SpectralGapAnalysis
    effective_convergence_rate: float
    steps_to_half_energy: float


def analyze_operator_convergence(
    G: Any,
    name_or_glyph: str,
) -> LyapunovSpectralSummary:
    r"""Combine per-operator Lyapunov bound with spectral gap analysis.

    For stabilisers, the effective convergence rate is the tighter of
    the operator's contraction rate ρ and the graph's canonical diffusion
    relaxation gap λ₂(L_sym) (``diffusion_gap``, the structural_diffusion
    relaxation rate — not the combinatorial algebraic connectivity).
    The number of steps to halve energy is ln(2)/rate.

    Parameters
    ----------
    G : networkx.Graph
        The TNFR network.
    name_or_glyph : str
        Operator name or glyph.

    Returns
    -------
    LyapunovSpectralSummary
    """
    bound = get_bound(name_or_glyph)
    spectral = analyze_spectral_gap(G)

    if bound.energy_class == EnergyClass.STABILISER:
        # The diffusive relaxation bound is the CANONICAL diffusion gap
        # λ₂(L_sym) (= the structural_diffusion relaxation rate), not the
        # combinatorial algebraic connectivity.
        rate = min(bound.contraction_rate, spectral.diffusion_gap)
        steps = math.log(2) / rate if rate > 1e-15 else float("inf")
    else:
        rate = 0.0
        steps = float("inf")

    return LyapunovSpectralSummary(
        operator_bound=bound,
        spectral=spectral,
        effective_convergence_rate=rate,
        steps_to_half_energy=steps,
    )


# ---------------------------------------------------------------------------
#  Grammar-compliant sequence analysis (U2 formal proof)
# ---------------------------------------------------------------------------


@dataclass(frozen=True)
class SequenceLyapunovProof:
    r"""Formal proof that a grammar-compliant sequence is net-contractive.

    Under U2, every destabiliser must be compensated by a stabiliser.
    This data structure records the per-step energy multipliers and
    verifies Π(1 + cᵢ) ≤ 1.

    Attributes
    ----------
    operators : tuple
        Operator names in sequence order.
    energy_multipliers : tuple
        Per-step multiplicative factors (1 + cᵢ).
        cᵢ < 0 for stabilisers, cᵢ > 0 for destabilisers.
    cumulative_product : float
        Π(1 + cᵢ) — net energy ratio E_final/E_initial (upper bound).
    is_net_contractive : bool
        True if cumulative_product ≤ 1.0 (Lyapunov stable).
    net_contraction : float
        1 - cumulative_product (positive = net energy decrease).
    """

    operators: tuple
    energy_multipliers: tuple
    cumulative_product: float
    is_net_contractive: bool
    net_contraction: float


def prove_sequence_lyapunov(
    operator_names: Sequence[str],
) -> SequenceLyapunovProof:
    r"""Formally verify that an operator sequence is net-contractive.

    Each operator contributes a multiplicative factor to the energy:
    - Stabiliser with rate ρ: factor = 1 - ρ  (< 1)
    - Destabiliser with rate κ: factor = 1 + κ  (> 1)
    - Neutral with residual ε: factor = 1 + ε  (≈ 1)
    - Mixed with rate κ: factor = 1 + κ  (worst case)

    The product Π factors gives the net energy ratio.  If ≤ 1, the
    sequence is Lyapunov stable per the Structural Conservation derivation.

    Parameters
    ----------
    operator_names : Sequence[str]
        Ordered list of operator names or glyphs.

    Returns
    -------
    SequenceLyapunovProof
    """
    multipliers = []
    for name in operator_names:
        bound = get_bound(name)
        if bound.energy_class == EnergyClass.STABILISER:
            factor = 1.0 - bound.contraction_rate
            # Ensure factor stays positive (physical constraint)
            factor = max(factor, 0.0)
        elif bound.energy_class == EnergyClass.DESTABILISER:
            factor = 1.0 + bound.contraction_rate
        elif bound.energy_class == EnergyClass.NEUTRAL:
            factor = 1.0 + bound.contraction_rate
        else:  # MIXED
            factor = 1.0 + bound.contraction_rate
        multipliers.append(factor)

    product = 1.0
    for f in multipliers:
        product *= f

    return SequenceLyapunovProof(
        operators=tuple(operator_names),
        energy_multipliers=tuple(multipliers),
        cumulative_product=product,
        is_net_contractive=product <= 1.0,
        net_contraction=1.0 - product,
    )


# ---------------------------------------------------------------------------
#  Public API
# ---------------------------------------------------------------------------

__all__ = [
    # Enums
    "EnergyClass",
    # Data structures
    "OperatorLyapunovBound",
    "OperatorLyapunovVerification",
    "SpectralGapAnalysis",
    "LyapunovSpectralSummary",
    "SequenceLyapunovProof",
    # Registry
    "OPERATOR_LYAPUNOV_BOUNDS",
    "get_bound",
    # Per-operator analysis
    "compute_operator_energy_bound",
    "verify_operator_lyapunov",
    # Sequence analysis
    "compute_sequence_energy_bound",
    "prove_sequence_lyapunov",
    # Spectral gap
    "analyze_spectral_gap",
    # Combined analysis
    "analyze_operator_convergence",
]