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/alias.py

alias.py

Attribute helpers supporting alias keys.

AliasAccessor provides the main implementation for dealing with alias-based attribute access. Legacy wrappers alias_get and alias_set have been removed; use :func:get_attr and :func:set_attr instead.

CRITICAL: Canonical Attribute Access

ALWAYS use the alias system for reading/writing TNFR attributes.

The TNFR canonical attribute keys use Unicode symbols (e.g., 'νf' for structural frequency), but NetworkX and Python code often use ASCII equivalents (e.g., 'vf'). This creates a critical inconsistency:

WRONG (breaks canonicity): >>> G.add_node(0, vf=1.0) # Uses ASCII 'vf' key >>> value = G.nodes[0]['vf'] # Reads ASCII 'vf' - may not exist! >>> G.nodes[0]['vf'] = 2.0 # Writes ASCII 'vf' - wrong key!

CORRECT (maintains canonicity): >>> from tnfr.alias import set_vf, get_attr >>> from tnfr.constants.aliases import ALIAS_VF >>> from tnfr.constants import VF_PRIMARY >>> >>> # For initialization, use canonical setters: >>> set_vf(G, 0, 1.0) # Writes to 'νf' (Greek nu) >>> >>> # For reading, use canonical getters: >>> value = get_attr(G.nodes[0], ALIAS_VF, 0.0) # Reads from 'νf' >>> >>> # Or use PRIMARY constants in add_node: >>> G.add_node(1, **{VF_PRIMARY: 1.0}) # Writes to 'νf' directly

Why This Matters:

  • The alias system tries ALL aliases in order: ('νf', 'nu_f', 'nu-f', 'nu', 'freq', 'frequency')
  • If you write to 'vf', the data is stored under a key NOT in the alias list
  • Reading via get_attr() will return the default (0.0) instead of your value
  • This breaks the nodal equation: ∂EPI/∂t = νf · ΔNFR(t)

For Tests: >>> from tnfr.structural import create_nfr >>> # PREFERRED: Use create_nfr which handles canonicity >>> G, node = create_nfr("test", vf=1.0, epi=0.5, theta=0.0) >>> >>> # ALTERNATIVE: Manual initialization with canonical setters >>> from tnfr.alias import set_vf, get_attr >>> from tnfr.constants.aliases import ALIAS_VF >>> G = nx.Graph() >>> G.add_node(0, theta=0.0, EPI=1.0, Si=0.5) # Other attrs OK >>> set_vf(G, 0, 1.0) # Use canonical setter for vf >>> value = get_attr(G.nodes[0], ALIAS_VF, 0.0) # Use canonical getter

Applies to: νf (vf), θ (theta), ΔNFR (dnfr), and other aliased attributes. See ALIAS_VF, ALIAS_THETA, ALIAS_DNFR in tnfr.constants.aliases for full lists.

Source Code

python
"""Attribute helpers supporting alias keys.

``AliasAccessor`` provides the main implementation for dealing with
alias-based attribute access. Legacy wrappers ``alias_get`` and
``alias_set`` have been removed; use :func:`get_attr` and
:func:`set_attr` instead.

CRITICAL: Canonical Attribute Access
=====================================

**ALWAYS use the alias system for reading/writing TNFR attributes.**

The TNFR canonical attribute keys use Unicode symbols (e.g., 'νf' for structural
frequency), but NetworkX and Python code often use ASCII equivalents (e.g., 'vf').
This creates a critical inconsistency:

**WRONG (breaks canonicity)**:
    >>> G.add_node(0, vf=1.0)           # Uses ASCII 'vf' key
    >>> value = G.nodes[0]['vf']         # Reads ASCII 'vf' - may not exist!
    >>> G.nodes[0]['vf'] = 2.0           # Writes ASCII 'vf' - wrong key!

**CORRECT (maintains canonicity)**:
    >>> from tnfr.alias import set_vf, get_attr
    >>> from tnfr.constants.aliases import ALIAS_VF
    >>> from tnfr.constants import VF_PRIMARY
    >>>
    >>> # For initialization, use canonical setters:
    >>> set_vf(G, 0, 1.0)                # Writes to 'νf' (Greek nu)
    >>>
    >>> # For reading, use canonical getters:
    >>> value = get_attr(G.nodes[0], ALIAS_VF, 0.0)  # Reads from 'νf'
    >>>
    >>> # Or use PRIMARY constants in add_node:
    >>> G.add_node(1, **{VF_PRIMARY: 1.0})  # Writes to 'νf' directly

**Why This Matters**:
- The alias system tries ALL aliases in order: ('νf', 'nu_f', 'nu-f', 'nu', 'freq', 'frequency')
- If you write to 'vf', the data is stored under a key NOT in the alias list
- Reading via get_attr() will return the default (0.0) instead of your value
- This breaks the nodal equation: ∂EPI/∂t = νf · ΔNFR(t)

**For Tests**:
    >>> from tnfr.structural import create_nfr
    >>> # PREFERRED: Use create_nfr which handles canonicity
    >>> G, node = create_nfr("test", vf=1.0, epi=0.5, theta=0.0)
    >>>
    >>> # ALTERNATIVE: Manual initialization with canonical setters
    >>> from tnfr.alias import set_vf, get_attr
    >>> from tnfr.constants.aliases import ALIAS_VF
    >>> G = nx.Graph()
    >>> G.add_node(0, theta=0.0, EPI=1.0, Si=0.5)  # Other attrs OK
    >>> set_vf(G, 0, 1.0)                          # Use canonical setter for vf
    >>> value = get_attr(G.nodes[0], ALIAS_VF, 0.0)  # Use canonical getter

**Applies to**: νf (vf), θ (theta), ΔNFR (dnfr), and other aliased attributes.
See ALIAS_VF, ALIAS_THETA, ALIAS_DNFR in tnfr.constants.aliases for full lists.
"""

from __future__ import annotations

from collections import defaultdict
from collections.abc import Iterable, Mapping, MutableMapping, Sized
from functools import lru_cache, partial
from threading import Lock
from typing import TYPE_CHECKING, Any, Callable, Generic, Hashable, TypeVar, cast

from .compat.dataclass import dataclass
from .constants.aliases import ALIAS_DNFR, ALIAS_THETA, ALIAS_VF
from .mathematics.unified_numerical import np
from .types import FloatArray, NodeId
from .utils import convert_value

if TYPE_CHECKING:  # pragma: no cover
    import networkx

T = TypeVar("T")


def _bepi_to_float(value: Any) -> float:
    """Extract scalar from BEPIElement dict or convert value to float.

    When operators transform EPI from float to BEPIElement dict, this helper
    extracts the maximum magnitude from the 'continuous' component. This
    preserves ΔNFR semantics (§3.3) and structural metrics accuracy (§3.9).

    Parameters
    ----------
    value : Any
        Value to convert. If it's a dict with a 'continuous' key, extracts
        the maximum magnitude. Otherwise converts directly to float.

    Returns
    -------
    float
        Scalar representation of the value.
    """
    if isinstance(value, dict) and "continuous" in value:
        cont = value["continuous"]
        if isinstance(cont, tuple):
            return float(max(abs(c) for c in cont)) if cont else 0.0
        return float(abs(cont))
    return float(value)


@lru_cache(maxsize=128)
def _alias_cache(alias_tuple: tuple[str, ...]) -> tuple[str, ...]:
    """Validate and cache alias tuples.

    ``functools.lru_cache`` protects this function with an internal lock,
    which is sufficient for thread-safe access; no explicit locking is
    required.
    """
    if not alias_tuple:
        raise ValueError("'aliases' must contain at least one key")
    if not all(isinstance(a, str) for a in alias_tuple):
        raise TypeError("'aliases' elements must be strings")
    return alias_tuple


class AliasAccessor(Generic[T]):
    """Helper providing ``get`` and ``set`` for alias-based attributes.

    This class implements all logic for resolving and assigning values
    using alias keys. Helper functions :func:`get_attr` and
    :func:`set_attr` delegate to a module-level instance of this class.
    """

    def __init__(
        self, conv: Callable[[Any], T] | None = None, default: T | None = None
    ) -> None:
        self._conv = conv
        self._default = default
        # expose cache for testing and manual control
        self._alias_cache = _alias_cache
        self._key_cache: dict[tuple[int, tuple[str, ...]], tuple[str, int]] = {}
        self._lock = Lock()

    def _prepare(
        self,
        aliases: Iterable[str],
        conv: Callable[[Any], T] | None,
        default: T | None = None,
    ) -> tuple[tuple[str, ...], Callable[[Any], T], T | None]:
        """Validate ``aliases`` and resolve ``conv`` and ``default``.

        Parameters
        ----------
        aliases:
            Iterable of alias strings. Must not be a single string.
        conv:
            Conversion callable. If ``None``, the accessor's default
            converter is used.
        default:
            Default value to use if no alias is found. If ``None``, the
            accessor's default is used.
        """

        if isinstance(aliases, str) or not isinstance(aliases, Iterable):
            raise TypeError("'aliases' must be a non-string iterable")
        aliases = _alias_cache(tuple(aliases))
        if conv is None:
            conv = self._conv
        if conv is None:
            raise TypeError("'conv' must be provided")
        if default is None:
            default = self._default
        return aliases, conv, default

    def _resolve_cache_key(
        self, d: dict[str, Any], aliases: tuple[str, ...]
    ) -> tuple[tuple[int, tuple[str, ...]], str | None]:
        """Return cache entry for ``d`` and ``aliases`` if still valid.

        The mapping remains coherent only when the cached key exists in
        ``d`` and the dictionary size has not changed. Invalid entries are
        removed to preserve structural consistency.
        """

        cache_key = (id(d), aliases)
        with self._lock:
            cached = self._key_cache.get(cache_key)
        if cached is not None:
            key, size = cached
            if size == len(d) and key in d:
                return cache_key, key
            with self._lock:
                self._key_cache.pop(cache_key, None)
        return cache_key, None

    def get(
        self,
        d: dict[str, Any],
        aliases: Iterable[str],
        default: T | None = None,
        *,
        strict: bool = False,
        log_level: int | None = None,
        conv: Callable[[Any], T] | None = None,
    ) -> T | None:
        """Return ``value`` for the first alias present in ``d``."""

        aliases, conv, default = self._prepare(aliases, conv, default)
        cache_key, key = self._resolve_cache_key(d, aliases)
        if key is not None:
            ok, value = convert_value(
                d[key], conv, strict=strict, key=key, log_level=log_level
            )
            if ok:
                return value
        for key in aliases:
            if key in d:
                ok, value = convert_value(
                    d[key], conv, strict=strict, key=key, log_level=log_level
                )
                if ok:
                    with self._lock:
                        self._key_cache[cache_key] = (key, len(d))
                    return value
        if default is not None:
            ok, value = convert_value(
                default,
                conv,
                strict=strict,
                key="default",
                log_level=log_level,
            )
            if ok:
                return value
        return None

    def set(
        self,
        d: dict[str, Any],
        aliases: Iterable[str],
        value: Any,
        conv: Callable[[Any], T] | None = None,
    ) -> T:
        """Write ``value`` under the first matching alias and cache the choice."""

        aliases, conv, _ = self._prepare(aliases, conv)
        cache_key, key = self._resolve_cache_key(d, aliases)
        if key is not None:
            d[key] = conv(value)
            return d[key]
        key = next((k for k in aliases if k in d), aliases[0])
        val = conv(value)
        d[key] = val
        with self._lock:
            self._key_cache[cache_key] = (key, len(d))
        return val


_generic_accessor: AliasAccessor[Any] = AliasAccessor()


def get_theta_attr(
    d: Mapping[str, Any],
    default: T | None = None,
    *,
    strict: bool = False,
    log_level: int | None = None,
    conv: Callable[[Any], T] = float,
) -> T | None:
    """Return ``theta``/``phase`` using the English alias set."""
    return _generic_accessor.get(
        cast(dict[str, Any], d),
        ALIAS_THETA,
        default,
        strict=strict,
        log_level=log_level,
        conv=conv,
    )


def get_attr(
    d: dict[str, Any],
    aliases: Iterable[str],
    default: T | None = None,
    *,
    strict: bool = False,
    log_level: int | None = None,
    conv: Callable[[Any], T] = _bepi_to_float,
) -> T | None:
    """Return the value for the first key in ``aliases`` found in ``d``.

    WARNING: This function searches for keys in alias order. If you manually
    wrote to a non-canonical key (e.g., 'vf' instead of 'νf'), this function
    will NOT find it and will return the default value instead.

    For structural frequency: ALWAYS use set_vf() to write, not d['vf'] = value.
    See module docstring for detailed guidance on canonical attribute access.
    """

    return _generic_accessor.get(
        d,
        aliases,
        default=default,
        strict=strict,
        log_level=log_level,
        conv=conv,
    )


def collect_attr(
    G: "networkx.Graph",
    nodes: Iterable[NodeId],
    aliases: Iterable[str],
    default: float = 0.0,
) -> FloatArray | list[float]:
    """Collect attribute values for ``nodes`` from ``G`` using ``aliases``.

    Parameters
    ----------
    G:
        Graph containing node attribute mappings.
    nodes:
        Iterable of node identifiers to query.
    aliases:
        Sequence of alias keys passed to :func:`get_attr`.
    default:
        Fallback value when no alias is found for a node.

    Returns
    -------
    list or numpy.ndarray
        Collected attribute values in the same order as ``nodes``.
    """

    def _nodes_iter_and_size(nodes: Iterable[NodeId]) -> tuple[Iterable[NodeId], int]:
        if nodes is G.nodes:
            return G.nodes, G.number_of_nodes()
        if isinstance(nodes, Sized):
            return nodes, len(nodes)  # type: ignore[arg-type]
        nodes_list = list(nodes)
        return nodes_list, len(nodes_list)

    nodes_iter, size = _nodes_iter_and_size(nodes)

    def _value(node: NodeId) -> float:
        val = get_attr(G.nodes[node], aliases, default)
        return float(val) if val is not None else default

    if np is not None:
        values: FloatArray = np.fromiter(
            (_value(n) for n in nodes_iter), float, count=size
        )
        return values
    return [_value(n) for n in nodes_iter]


def collect_theta_attr(
    G: "networkx.Graph",
    nodes: Iterable[NodeId],
    default: float = 0.0,
) -> FloatArray | list[float]:
    """Collect ``theta`` values honouring the English-only attribute contract."""

    def _nodes_iter_and_size(nodes: Iterable[NodeId]) -> tuple[Iterable[NodeId], int]:
        if nodes is G.nodes:
            return G.nodes, G.number_of_nodes()
        if isinstance(nodes, Sized):
            return nodes, len(nodes)  # type: ignore[arg-type]
        nodes_list = list(nodes)
        return nodes_list, len(nodes_list)

    nodes_iter, size = _nodes_iter_and_size(nodes)

    def _value(node: NodeId) -> float:
        return cast(float, get_theta_attr(G.nodes[node], default))

    if np is not None:
        values: FloatArray = np.fromiter(
            (_value(n) for n in nodes_iter), float, count=size
        )
        return values

    return [_value(n) for n in nodes_iter]


def set_attr_generic(
    d: dict[str, Any],
    aliases: Iterable[str],
    value: Any,
    *,
    conv: Callable[[Any], T],
) -> T:
    """Assign ``value`` to the FIRST (canonical) alias key in ``aliases``.

    CRITICAL: This function writes to the FIRST key in the alias tuple.
    For ALIAS_VF = ('νf', 'nu_f', ...), this writes to 'νf' (Greek nu), NOT 'vf'.

    If you later try to read with G.nodes[n]['vf'], you will NOT find the value.
    ALWAYS use get_attr() to read what set_attr() wrote.

    For high-level usage, prefer set_vf(), set_theta(), etc. which handle this correctly.
    See module docstring for detailed guidance on canonical attribute access.
    """

    return _generic_accessor.set(d, aliases, value, conv=conv)


set_attr = partial(set_attr_generic, conv=float)

get_attr_str = partial(get_attr, conv=str)
set_attr_str = partial(set_attr_generic, conv=str)


def set_theta_attr(d: MutableMapping[str, Any], value: Any) -> float:
    """Assign ``theta``/``phase`` using the English attribute names."""
    result = float(value)
    d["theta"] = result
    d["phase"] = result
    return result


# -------------------------
# Cached global maxima
# -------------------------


@dataclass(slots=True)
@dataclass
class AbsMaxResult:
    """Absolute maximum value and the node where it occurs."""

    max_value: float
    node: Hashable | None


def _coerce_abs_value(value: Any) -> float:
    """Return ``value`` as ``float`` treating ``None`` as ``0.0``."""

    if value is None:
        return 0.0
    try:
        return _bepi_to_float(value)
    except (TypeError, ValueError):
        return 0.0


def _compute_abs_max_result(
    G: "networkx.Graph",
    aliases: tuple[str, ...],
    *,
    key: str | None = None,
    candidate: tuple[Hashable, float] | None = None,
) -> AbsMaxResult:
    """Return the absolute maximum (and node) for ``aliases``.

    Parameters
    ----------
    G:
        Graph containing nodal data.
    aliases:
        Attribute aliases to inspect.
    key:
        Cache key to update. When ``None``, the graph cache is untouched.
    candidate:
        Optional ``(node, value)`` pair representing a candidate maximum.

    Returns
    -------
    AbsMaxResult
        Structure holding the absolute maximum and the node where it
        occurs. When ``candidate`` is provided, its value is treated as the
        current maximum and no recomputation is performed.
    """

    if candidate is not None:
        node, value = candidate
        max_val = abs(float(value))
    else:
        node, max_val = max(
            (
                (n, abs(cast(float, get_attr(G.nodes[n], aliases, 0.0))))
                for n in G.nodes()
            ),
            key=lambda item: item[1],
            default=(None, 0.0),
        )
        max_val = float(max_val)

    if key is not None:
        G.graph[key] = max_val
        G.graph[f"{key}_node"] = node

    return AbsMaxResult(max_value=max_val, node=node)


def multi_recompute_abs_max(
    G: "networkx.Graph", alias_map: dict[str, tuple[str, ...]]
) -> dict[str, float]:
    """Return absolute maxima for each entry in ``alias_map``.

    ``G`` is a :class:`networkx.Graph`. ``alias_map`` maps result keys to
    alias tuples. The graph is traversed once and the absolute maximum for
    each alias tuple is recorded. The returned dictionary uses the same
    keys as ``alias_map``.
    """

    maxima: defaultdict[str, float] = defaultdict(float)
    items = list(alias_map.items())
    for _, nd in G.nodes(data=True):
        maxima.update(
            {
                key: max(maxima[key], abs(cast(float, get_attr(nd, aliases, 0.0))))
                for key, aliases in items
            }
        )
    return {k: float(v) for k, v in maxima.items()}


def _update_cached_abs_max(
    G: "networkx.Graph",
    aliases: tuple[str, ...],
    n: Hashable,
    value: float,
    *,
    key: str,
) -> AbsMaxResult:
    """Update cached absolute maxima for ``aliases``.

    The current cached value is updated when ``value`` becomes the new
    maximum or when the stored node matches ``n`` but its magnitude
    decreases. The returned :class:`AbsMaxResult` always reflects the
    cached maximum after applying the update.
    """

    node_key = f"{key}_node"
    val = abs(float(value))
    cur = _coerce_abs_value(G.graph.get(key))
    cur_node = cast(Hashable | None, G.graph.get(node_key))

    if val >= cur:
        return _compute_abs_max_result(G, aliases, key=key, candidate=(n, val))
    if cur_node == n:
        return _compute_abs_max_result(G, aliases, key=key)
    return AbsMaxResult(max_value=cur, node=cur_node)


def set_attr_and_cache(
    G: "networkx.Graph",
    n: Hashable,
    aliases: tuple[str, ...],
    value: float,
    *,
    cache: str | None = None,
    extra: Callable[["networkx.Graph", Hashable, float], None] | None = None,
) -> AbsMaxResult | None:
    """Assign ``value`` to node ``n`` and optionally update cached maxima.

    Returns
    -------
    AbsMaxResult | None
        Absolute maximum information when ``cache`` is provided; otherwise
        ``None``.
    """

    val = set_attr(G.nodes[n], aliases, value)
    result: AbsMaxResult | None = None
    if cache is not None:
        result = _update_cached_abs_max(G, aliases, n, val, key=cache)
    if extra is not None:
        extra(G, n, val)
    return result


def set_attr_with_max(
    G: "networkx.Graph",
    n: Hashable,
    aliases: tuple[str, ...],
    value: float,
    *,
    cache: str,
) -> AbsMaxResult:
    """Assign ``value`` to node ``n`` and update the global maximum.

    This is a convenience wrapper around :func:`set_attr_and_cache`.
    """
    return cast(
        AbsMaxResult,
        set_attr_and_cache(G, n, aliases, value, cache=cache),
    )


def set_scalar(
    G: "networkx.Graph",
    n: Hashable,
    alias: tuple[str, ...],
    value: float,
    *,
    cache: str | None = None,
    extra: Callable[["networkx.Graph", Hashable, float], None] | None = None,
) -> AbsMaxResult | None:
    """Assign ``value`` to ``alias`` for node ``n`` and update caches.

    Returns
    -------
    AbsMaxResult | None
        Updated absolute maximum details when ``cache`` is provided.
    """

    return set_attr_and_cache(G, n, alias, value, cache=cache, extra=extra)


def _increment_trig_version(G: "networkx.Graph", _: Hashable, __: float) -> None:
    """Increment cached trig version to invalidate trig caches."""
    g = G.graph
    g["_trig_version"] = int(g.get("_trig_version", 0)) + 1


SCALAR_SETTERS: dict[str, dict[str, Any]] = {
    "vf": {
        "alias": ALIAS_VF,
        "cache": "_vfmax",
        "doc": "set ``νf`` for node ``n`` and optionally update the global maximum.",
        "update_max_param": True,
    },
    "dnfr": {
        "alias": ALIAS_DNFR,
        "cache": "_dnfrmax",
        "doc": "set ``ΔNFR`` for node ``n`` and update the global maximum.",
    },
    "theta": {
        "alias": ALIAS_THETA,
        "extra": _increment_trig_version,
        "doc": "set ``theta`` for node ``n`` and invalidate trig caches.",
    },
}


def _make_scalar_setter(
    name: str, spec: dict[str, Any]
) -> Callable[..., AbsMaxResult | None]:
    alias = spec["alias"]
    cache = spec.get("cache")
    extra = spec.get("extra")
    doc = spec.get("doc")
    has_update = spec.get("update_max_param", False)

    if has_update:

        def setter(
            G: "networkx.Graph",
            n: Hashable,
            value: float,
            *,
            update_max: bool = True,
        ) -> AbsMaxResult | None:
            cache_key = cache if update_max else None
            return set_scalar(G, n, alias, value, cache=cache_key, extra=extra)

    else:

        def setter(
            G: "networkx.Graph", n: Hashable, value: float
        ) -> AbsMaxResult | None:
            return set_scalar(G, n, alias, value, cache=cache, extra=extra)

    setter.__name__ = f"set_{name}"
    setter.__qualname__ = f"set_{name}"
    setter.__doc__ = doc
    return setter


for _name, _spec in SCALAR_SETTERS.items():
    globals()[f"set_{_name}"] = _make_scalar_setter(_name, _spec)

del _name, _spec, _make_scalar_setter

_set_theta_impl = cast(
    Callable[["networkx.Graph", Hashable, float], AbsMaxResult | None],
    globals()["set_theta"],
)


def _set_theta_with_compat(
    G: "networkx.Graph", n: Hashable, value: float
) -> AbsMaxResult | None:
    nd = cast(MutableMapping[str, Any], G.nodes[n])
    result = _set_theta_impl(G, n, value)
    theta_val = get_theta_attr(nd, value)
    if theta_val is not None:
        float_theta = float(theta_val)
        nd["theta"] = float_theta
        nd["phase"] = float_theta
    return result


_set_theta_with_compat.__name__ = "set_theta"
_set_theta_with_compat.__qualname__ = "set_theta"
_set_theta_with_compat.__doc__ = _set_theta_impl.__doc__
globals()["set_theta"] = _set_theta_with_compat

__all__ = [
    "AbsMaxResult",
    "set_attr_generic",
    "get_attr",
    "get_theta_attr",
    "collect_attr",
    "collect_theta_attr",
    "set_attr",
    "get_attr_str",
    "set_attr_str",
    "set_theta_attr",
    "set_attr_and_cache",
    "set_attr_with_max",
    "set_scalar",
    "SCALAR_SETTERS",
    *[f"set_{name}" for name in SCALAR_SETTERS],
    "multi_recompute_abs_max",
]