-
Notifications
You must be signed in to change notification settings - Fork 0
[THOL][Canonical] Verify phase validation in sub-EPI propagation (Invariant #5) #2872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e61f58e
b15336b
ead485e
d51ffd5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -578,6 +578,164 @@ Ensure the added operator makes **semantic sense** for your application: | |||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Phase Compatibility in Propagation | ||||||
|
|
||||||
| **CRITICAL**: THOL propagation respects **AGENTS.md Invariant #5**: "No coupling is valid without explicit phase verification." | ||||||
|
|
||||||
| ### Physical Basis | ||||||
|
|
||||||
| Sub-EPI propagation follows resonance physics, not arbitrary connectivity. Antiphase nodes (Δθ ≈ π) create **destructive interference**, preventing coherent propagation regardless of network topology. | ||||||
|
|
||||||
| ### Implementation | ||||||
|
|
||||||
| From `src/tnfr/operators/metabolism.py::propagate_subepi_to_network()`: | ||||||
|
|
||||||
| ```python | ||||||
| # Compute coupling strength (phase alignment) | ||||||
| phase_diff = abs(angle_diff(neighbor_theta, parent_theta)) | ||||||
| coupling_strength = 1.0 - (phase_diff / math.pi) | ||||||
|
|
||||||
| # Propagate only if sufficiently coupled | ||||||
| if coupling_strength >= min_coupling_strength: | ||||||
| # Attenuate and inject sub-EPI | ||||||
| attenuated_epi = sub_epi_magnitude * attenuation * coupling_strength | ||||||
| # ... | ||||||
| ``` | ||||||
|
|
||||||
| **Formula**: | ||||||
| ``` | ||||||
| coupling_strength = 1.0 - (|Δθ| / π) | ||||||
| ``` | ||||||
|
|
||||||
| Where: | ||||||
| - `Δθ` = phase difference between parent and neighbor (radians) | ||||||
| - `coupling_strength` ∈ [0, 1] | ||||||
| - Propagation occurs only if `coupling_strength ≥ threshold` (default: 0.5) | ||||||
|
|
||||||
| ### Phase Compatibility Table | ||||||
|
|
||||||
| | Phase Difference (Δθ) | Coupling Strength | Propagates? (threshold=0.5) | Physics | | ||||||
| |----------------------|-------------------|---------------------------|---------| | ||||||
| | 0 (in-phase) | 1.0 | ✅ Yes | Perfect resonance | | ||||||
| | π/4 (45°) | 0.75 | ✅ Yes | Strong coupling | | ||||||
| | π/2 (90°) | 0.5 | ✅ Yes (at threshold) | Moderate coupling | | ||||||
| | 3π/4 (135°) | 0.25 | ❌ No | Weak coupling | | ||||||
| | π (antiphase) | 0.0 | ❌ No | Destructive interference | | ||||||
|
|
||||||
| ### Canonical Constraints | ||||||
|
|
||||||
| **From AGENTS.md Invariant #5**: | ||||||
|
|
||||||
| Sub-EPIs propagate **ONLY** to neighbors with: | ||||||
| 1. **Phase compatibility**: `|Δθ| ≤ Δθ_max` (typically π/2) | ||||||
| 2. **Coupling threshold**: `coupling_strength ≥ threshold` (default: 0.5) | ||||||
| 3. **Explicit verification**: Phase difference computed before propagation | ||||||
|
|
||||||
| **Why This Matters**: | ||||||
|
|
||||||
| - **TNFR Physics**: Resonance requires phase alignment, not just network edges | ||||||
| - **Prevents Chaos**: Antiphase propagation would create destructive interference | ||||||
| - **Canonical Compliance**: Same phase verification as UM (Coupling) and RA (Resonance) | ||||||
|
|
||||||
| ### Example: Phase Barrier Blocking Cascade | ||||||
|
|
||||||
| ```python | ||||||
| import math | ||||||
| import networkx as nx | ||||||
| from tnfr.operators.definitions import SelfOrganization | ||||||
| from tnfr.constants import EPI_PRIMARY, THETA_PRIMARY, VF_PRIMARY, DNFR_PRIMARY | ||||||
|
|
||||||
| # Create network with phase barrier | ||||||
| G = nx.Graph() | ||||||
|
|
||||||
| # Cluster A: coherent phases | ||||||
| G.add_node(0, **{EPI_PRIMARY: 0.50, THETA_PRIMARY: 0.1, VF_PRIMARY: 1.0, DNFR_PRIMARY: 0.10}) | ||||||
| G.add_node(1, **{EPI_PRIMARY: 0.45, THETA_PRIMARY: 0.12, VF_PRIMARY: 1.0, DNFR_PRIMARY: 0.10}) | ||||||
|
|
||||||
| # Node 2: phase barrier (antiphase) | ||||||
| G.add_node(2, **{EPI_PRIMARY: 0.45, THETA_PRIMARY: math.pi, VF_PRIMARY: 1.0, DNFR_PRIMARY: 0.10}) | ||||||
|
|
||||||
| # Cluster B: isolated by barrier | ||||||
| G.add_node(3, **{EPI_PRIMARY: 0.45, THETA_PRIMARY: math.pi + 0.1, VF_PRIMARY: 1.0, DNFR_PRIMARY: 0.10}) | ||||||
|
|
||||||
| # Connect: 0-1-2-3 | ||||||
| G.add_edges_from([(0, 1), (1, 2), (2, 3)]) | ||||||
|
|
||||||
| # Enable propagation | ||||||
| G.graph["THOL_PROPAGATION_ENABLED"] = True | ||||||
| G.nodes[0]["epi_history"] = [0.05, 0.33, 0.50] # Bifurcation conditions | ||||||
|
|
||||||
| # Trigger cascade from node 0 | ||||||
| SelfOrganization()(G, 0) | ||||||
|
|
||||||
| # Result: Propagation reaches node 1, stops at phase barrier (node 2) | ||||||
| # Node 3 is NOT affected due to phase incompatibility | ||||||
| ``` | ||||||
|
|
||||||
| ### Testing Phase Verification | ||||||
|
|
||||||
| From `tests/integration/test_thol_propagation.py`: | ||||||
|
|
||||||
| ```python | ||||||
| def test_thol_rejects_antiphase_propagation(): | ||||||
| """THOL must reject propagation to antiphase neighbors (Invariant #5).""" | ||||||
| import math | ||||||
|
|
||||||
| G = nx.Graph() | ||||||
| G.add_node(0, epi=0.50, vf=1.0, theta=0.0, delta_nfr=0.15) | ||||||
| G.add_node(1, epi=0.50, vf=1.0, theta=math.pi, delta_nfr=0.05) # Antiphase | ||||||
| G.add_edge(0, 1) | ||||||
|
|
||||||
| G.graph["THOL_PROPAGATION_ENABLED"] = True | ||||||
| G.nodes[0]["epi_history"] = [0.05, 0.33, 0.50] | ||||||
|
|
||||||
| epi_1_before = G.nodes[1]["epi"] | ||||||
| SelfOrganization()(G, 0) | ||||||
| epi_1_after = G.nodes[1]["epi"] | ||||||
|
|
||||||
| # Antiphase neighbor should be rejected | ||||||
| assert epi_1_after == epi_1_before, "Invariant #5 violation" | ||||||
| ``` | ||||||
|
|
||||||
| ### Configuration | ||||||
|
|
||||||
| Control phase verification via graph parameters: | ||||||
|
|
||||||
| ```python | ||||||
| # Strict phase compatibility (default) | ||||||
| G.graph["THOL_MIN_COUPLING_FOR_PROPAGATION"] = 0.5 # Δθ ≤ π/2 | ||||||
|
|
||||||
| # Relaxed (allow weaker coupling) | ||||||
| G.graph["THOL_MIN_COUPLING_FOR_PROPAGATION"] = 0.3 # Δθ ≤ ~2.2 rad | ||||||
|
|
||||||
| # Very strict (only near-in-phase) | ||||||
| G.graph["THOL_MIN_COUPLING_FOR_PROPAGATION"] = 0.8 # Δθ ≤ ~0.6 rad | ||||||
| ``` | ||||||
|
|
||||||
| **Canonical Default**: 0.5 (π/2 maximum phase difference) | ||||||
|
|
||||||
| ### Cross-Operator Consistency | ||||||
|
|
||||||
| THOL phase verification is **consistent** with other TNFR operators: | ||||||
|
|
||||||
| | Operator | Phase Verification | Formula | Use Case | | ||||||
| |----------|-------------------|---------|----------| | ||||||
| | **UM** (Coupling) | Consensus phase | `arctan2(Σsin(θ), Σcos(θ))` | Bidirectional synchronization | | ||||||
| | **RA** (Resonance) | Circular mean | `\|⟨e^(iθ)⟩\|` (Kuramoto) | Network-wide propagation | | ||||||
| | **THOL** (Propagation) | Direct difference | `1.0 - (\|Δθ\| / π)` | Unidirectional sub-EPI transfer | | ||||||
|
|
||||||
| All three enforce phase compatibility before structural modifications, ensuring resonance physics integrity. | ||||||
|
|
||||||
| ### References | ||||||
|
|
||||||
| - **AGENTS.md**: Invariant #5 (Phase Verification) | ||||||
| - **UNIFIED_GRAMMAR_RULES.md**: U3 (Resonant Coupling) | ||||||
| - **src/tnfr/operators/metabolism.py**: Lines 284-331 (propagate_subepi_to_network) | ||||||
|
||||||
| - **src/tnfr/operators/metabolism.py**: Lines 284-331 (propagate_subepi_to_network) | |
| - **src/tnfr/operators/metabolism.py**: Lines 306-319 (phase verification in propagate_subepi_to_network) |
Copilot
AI
Nov 9, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The line reference for the test is inaccurate. The documentation states "Lines 220-290" but the actual test test_thol_rejects_antiphase_propagation spans lines 218-283.
The test definition starts at line 218 and the last assertion ends at line 283. Line 284 is blank, and line 285 starts the next class.
Consider updating to: "Lines 218-283 (test_thol_rejects_antiphase_propagation)"
| - **tests/integration/test_thol_propagation.py**: Lines 220-290 (test_thol_rejects_antiphase_propagation) | |
| - **tests/integration/test_thol_propagation.py**: Lines 218-283 (test_thol_rejects_antiphase_propagation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation example uses invalid attribute aliases that will not work with the TNFR alias system:
epishould beEPI(or valid aliases:psi,PSI,value)vfshould beνf(or valid aliases:nu_f,nu-f,nu,freq,frequency)The aliases
thetaanddelta_nfrare valid.According to
src/tnfr/config/tnfr_config.py, the ALIASES dictionary defines:("EPI", "psi", "PSI", "value")- lowercaseepiis not included("νf", "nu_f", "nu-f", "nu", "freq", "frequency")- lowercasevfis not includedThe actual test in
tests/integration/test_thol_propagation.pycorrectly uses the constantsEPI_PRIMARY,VF_PRIMARY,THETA_PRIMARY, andDNFR_PRIMARY.