Skip to content

Commit 3847758

Browse files
Copilotfermga
andcommitted
Document SHA operator νf reduction in code and add canonical test
Co-authored-by: fermga <203334638+fermga@users.noreply.github.com>
1 parent facbb24 commit 3847758

File tree

3 files changed

+85
-3
lines changed

3 files changed

+85
-3
lines changed

src/tnfr/operators/__init__.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -965,12 +965,20 @@ def _op_SHA(node: NodeProtocol, gf: GlyphFactors) -> None: # SHA — Silence
965965
stillness. EPI, ΔNFR, and phase remain unchanged, signalling a temporary
966966
suspension of structural evolution.
967967
968+
**TNFR Canonical Behavior:**
969+
970+
According to the nodal equation ∂EPI/∂t = νf · ΔNFR(t), reducing νf → νf_min ≈ 0
971+
causes structural evolution to freeze (∂EPI/∂t → 0) regardless of ΔNFR magnitude.
972+
This implements **structural silence** - a state where the node's form (EPI) is
973+
preserved intact despite external pressures, enabling memory consolidation and
974+
protective latency.
975+
968976
Parameters
969977
----------
970978
node : NodeProtocol
971979
Node whose νf is being attenuated.
972980
gf : GlyphFactors
973-
Provides ``SHA_vf_factor`` to scale νf.
981+
Provides ``SHA_vf_factor`` to scale νf (default 0.85 for gradual reduction).
974982
975983
Examples
976984
--------
@@ -983,6 +991,8 @@ def _op_SHA(node: NodeProtocol, gf: GlyphFactors) -> None: # SHA — Silence
983991
0.5
984992
"""
985993
factor = get_factor(gf, "SHA_vf_factor", 0.85)
994+
# Canonical SHA effect: reduce structural frequency toward zero
995+
# This implements: νf → νf_min ≈ 0 ⇒ ∂EPI/∂t → 0 (structural preservation)
986996
node.vf = factor * node.vf
987997

988998

src/tnfr/operators/grammar.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,6 +1727,10 @@ def apply_glyph_with_grammar(
17271727
) -> None:
17281728
"""Apply glyph with grammar-based validation and coherence sequence recognition.
17291729
1730+
This function is the canonical entry point for applying structural operators through
1731+
the grammar layer. It enforces TNFR grammar rules, validates operator preconditions,
1732+
and tracks operator sequences for telemetry.
1733+
17301734
Enhanced to recognize and log canonical coherence sequences when they
17311735
occur in the glyph history. This enables pattern detection, telemetry, and
17321736
future optimization of common structural patterns.
@@ -1738,13 +1742,31 @@ def apply_glyph_with_grammar(
17381742
nodes : Optional[Iterable[NodeId | NodeProtocol]]
17391743
Target nodes (all nodes if None)
17401744
glyph : Glyph | str
1741-
Glyph to apply
1745+
Glyph to apply (e.g., Glyph.SHA for Silence operator)
17421746
window : Optional[int]
17431747
Hysteresis window (uses graph default if None)
17441748
17451749
Notes
17461750
-----
1747-
**Coherence Sequence Recognition** (New):
1751+
**Structural Operator Effects:**
1752+
1753+
This function delegates to operator-specific implementations that enforce
1754+
TNFR canonical behavior. Key operator effects include:
1755+
1756+
- **SHA (Silence)**: Reduces νf → νf_min ≈ 0, causing ∂EPI/∂t → 0
1757+
(structural evolution freezes). EPI preserved intact regardless of ΔNFR.
1758+
Implements structural silence for memory consolidation and protective latency.
1759+
1760+
- **AL (Emission)**: Increases νf and initiates positive ΔNFR for pattern activation
1761+
1762+
- **IL (Coherence)**: Reduces |ΔNFR| and stabilizes EPI form
1763+
1764+
- **OZ (Dissonance)**: Increases |ΔNFR| for exploration and bifurcation
1765+
1766+
See operator definitions in ``tnfr.operators.definitions`` for complete
1767+
canonical behavior specifications.
1768+
1769+
**Coherence Sequence Recognition:**
17481770
17491771
When a glyph is applied, the function checks if it forms a canonical coherence
17501772
sequence with the previous glyph in the node's history. Recognized patterns

tests/unit/operators/test_operator_enhancements.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,56 @@ def test_silence_precondition_minimal_vf(self):
9797
with pytest.raises(OperatorPreconditionError, match="already minimal"):
9898
Silence()(G, "n1")
9999

100+
def test_silence_canonical_vf_reduction(self):
101+
"""SHA - Canonical behavior: νf reduction below threshold with EPI preservation.
102+
103+
Validates TNFR canonical invariant for SHA operator:
104+
- νf → νf_min ≈ 0 (structural frequency reduction)
105+
- EPI(t + Δt) ≈ EPI(t) (form preservation)
106+
- ∂EPI/∂t → 0 (structural evolution freezes)
107+
108+
This test ensures apply_glyph_with_grammar correctly reduces νf
109+
through the operator chain when SHA is applied.
110+
"""
111+
# Create node with active νf and established EPI
112+
G = nx.DiGraph()
113+
G.add_node("n1", **{EPI_PRIMARY: 0.51, VF_PRIMARY: 1.00})
114+
G.graph["SHA_MIN_VF"] = 0.01 # Configure threshold
115+
G.graph["SHA_vf_factor"] = 0.85 # Explicit reduction factor
116+
117+
# Record state before SHA
118+
epi_before = G.nodes["n1"][EPI_PRIMARY]
119+
vf_before = G.nodes["n1"][VF_PRIMARY]
120+
121+
# Apply SHA through operator (canonical path via grammar layer)
122+
Silence()(G, "n1")
123+
124+
# Get state after SHA
125+
epi_after = G.nodes["n1"][EPI_PRIMARY]
126+
vf_after = G.nodes["n1"][VF_PRIMARY]
127+
128+
# Validate canonical SHA effects:
129+
# 1. νf explicitly reduced (primary effect)
130+
assert vf_after < vf_before, "SHA must reduce νf"
131+
assert vf_after == pytest.approx(vf_before * 0.85, abs=0.01), \
132+
"SHA should reduce νf by configured factor"
133+
134+
# 2. νf approaches minimum (structural silence)
135+
# After one application: 1.0 * 0.85 = 0.85
136+
# We verify it's moving toward zero
137+
assert vf_after < 1.0, "νf should decrease toward structural silence"
138+
139+
# 3. EPI preserved (form invariance during silence)
140+
assert abs(epi_after - epi_before) < 1e-6, \
141+
"SHA must preserve EPI (structural form)"
142+
143+
# 4. Verify metrics track the reduction (using centralized function)
144+
from tnfr.operators.metrics import silence_metrics
145+
metrics = silence_metrics(G, "n1", vf_before, epi_before)
146+
assert metrics["vf_reduction"] == pytest.approx(vf_before - vf_after, abs=0.01)
147+
assert metrics["epi_preservation"] < 1e-6, \
148+
"Metrics should confirm EPI preservation"
149+
100150
def test_expansion_precondition_max_vf(self):
101151
"""VAL - Expansion should fail if νf at maximum."""
102152
G = nx.DiGraph()

0 commit comments

Comments
 (0)