@@ -793,31 +793,61 @@ def _consume(self, token: str, index: int) -> None:
793793 if canonical == DISSONANCE :
794794 self ._found_dissonance = True
795795
796- # Track THOL state: Structural time with automatic closure
796+ # Track THOL state: Bifurcation window with automatic validation-based closure
797797 #
798- # TNFR Structural Time Principle: THOL closure emerges from bifurcation completion,
799- # not from operator detection. Internal sequences are equivalent to external ones.
798+ # TNFR Bifurcation Window Principle: THOL window closes when internal sequence is valid
799+ # - THOL opens bifurcation window
800+ # - Window accumulates operators
801+ # - When sequence reaches valid end operator, try to validate
802+ # - If valid: close window automatically
803+ # - If not valid: continue accumulating
800804 #
801- # Implementation for static validation:
802- # - THOL opens a nested context
803- # - Operators inside THOL are treated as normal sequence (can include SILENCE, etc.)
804- # - THOL closes automatically at sequence end or parent THOL closure
805- # - Nested THOL are supported (operational fractality)
805+ # This allows internal sequences to be identical to external ones:
806+ # they self-close when complete, no explicit delimiter needed.
806807 #
807- # This allows internal sequences to be identical to external ones, including
808- # having their own THOL blocks and using any valid end operators.
808+ # Empty window allowed (no bifurcation case: ∂²EPI/∂t² ≤ τ)
809809 if canonical == SELF_ORGANIZATION :
810- # THOL opening: push to stack and initialize subsequence
810+ # THOL opening: push to stack and initialize bifurcation window
811811 self ._thol_stack .append (index )
812812 self ._thol_subsequences [index ] = []
813813 self ._open_thol = True
814814 elif self ._open_thol and self ._thol_stack :
815815 current_thol = self ._thol_stack [- 1 ]
816+ window_content = self ._thol_subsequences [current_thol ]
816817
817- # All operators inside THOL are added to subsequence
818- # No operator-based closure detection - THOL closes structurally
819- # This allows internal sequences to be identical to external ones
818+ # Check if this is the first operator in window
819+ if len (window_content ) == 0 :
820+ # First operator after THOL opening
821+ # If it's not a valid start operator, window remains empty (no bifurcation)
822+ # and this operator belongs to external sequence
823+ if canonical not in VALID_START_OPERATORS :
824+ # Empty window - no bifurcation occurred
825+ # Close THOL immediately and process operator in parent context
826+ self ._thol_stack .pop ()
827+ self ._open_thol = bool (self ._thol_stack )
828+ # Don't add to window - process normally in parent context
829+ # (will be processed by subsequent validation logic)
830+ return
831+
832+ # Add operator to bifurcation window
820833 self ._thol_subsequences [current_thol ].append (canonical )
834+
835+ # Check if window is complete (sequence ends with valid end operator)
836+ # Try to close if last operator is a valid sequence end
837+ if canonical in VALID_END_OPERATORS and len (window_content ) > 0 :
838+ # Attempt to validate window as complete sequence
839+ try :
840+ # Create temporary automaton to test if window is valid
841+ test_automaton = _SequenceAutomaton ()
842+ test_automaton .run (self ._thol_subsequences [current_thol ])
843+
844+ # Validation succeeded - window is complete, close THOL
845+ self ._thol_stack .pop ()
846+ self ._open_thol = bool (self ._thol_stack )
847+
848+ except SequenceSyntaxError :
849+ # Window not yet complete/valid - continue accumulating
850+ pass
821851
822852 # Validate sequential compatibility if not first token
823853 # Only validate if both prev and current are known operators
@@ -1031,48 +1061,52 @@ def _validate_thol_subsequence(
10311061 end_index : int ,
10321062 end_token : str
10331063 ) -> None :
1034- """Validate recursively the subsequence within THOL block.
1064+ """Validate bifurcation window content within THOL block.
1065+
1066+ TNFR Bifurcation Window Principle: THOL requires explicit window that
1067+ contains bifurcation sequences. Window must be verified before proceeding.
10351068
1036- TNFR Physical Principle: THOL (self-organization) always applies as operator,
1037- but only generates sub-EPIs (and thus subsequence) if ∂²EPI/∂t² > τ .
1069+ Empty window is valid (THOL applied without bifurcation: ∂²EPI/∂t² ≤ τ).
1070+ Non-empty window must contain grammatically coherent sequence(s) .
10381071
1039- Empty THOL is physically valid - represents THOL application without bifurcation.
1040- Non-empty subsequence represents sub-EPIs and must respect grammar rules (C1-C4).
1072+ Window semantics (from @fermga's structural time insight):
1073+ - Window opened by THOL, closed by CONTRACTION
1074+ - Content represents bifurcation space
1075+ - If bifurcation occurs: sequences written in window
1076+ - If no bifurcation: window remains empty
1077+ - Only after window validation, sequence proceeds to next operator
10411078
10421079 Parameters
10431080 ----------
10441081 subsequence : list[str]
1045- Operators within THOL block (between opening and closure)
1082+ Operators within THOL bifurcation window
10461083 start_index : int
10471084 Index of THOL opening in parent sequence
10481085 end_index : int
1049- Index of THOL closure in parent sequence
1086+ Index of window closure in parent sequence
10501087 end_token : str
1051- Token used for closure (for error messages )
1088+ Token used for closure (CONTRACTION )
10521089
10531090 Raises
10541091 ------
10551092 SequenceSyntaxError
1056- If subsequence is invalid (when non-empty)
1093+ If window content is invalid (when non-empty)
10571094
10581095 Notes
10591096 -----
10601097 From TNFR Manual §3.2.2 (Ontología fractal resonante):
10611098 "Los NFRs pueden anidarse jerárquicamente: un nodo puede contener
10621099 nodos internos coherentes, dando lugar a una estructura fractal."
10631100
1064- From operator implementation: THOL bifurcates only if d2_epi > tau.
1065- This means THOL can appear without generating sub-EPIs (empty subsequence).
1066-
1067- When bifurcation occurs (non-empty subsequence), structures must be
1068- coherent at all scales - operational fractality is maintained.
1101+ Bifurcation window enables operational fractality while maintaining
1102+ explicit structural boundaries.
10691103 """
1070- # Empty THOL is valid: THOL applied but no bifurcation occurred
1104+ # Empty window is valid: THOL applied without bifurcation
10711105 if not subsequence :
10721106 return
10731107
1074- # Recursive grammar validation for non-empty subsequences
1075- # Create new automaton to validate subsequence independently
1108+ # Recursive grammar validation for non-empty bifurcation window
1109+ # Create new automaton to validate window content independently
10761110 try :
10771111 nested_automaton = _SequenceAutomaton ()
10781112 nested_automaton .run (subsequence )
@@ -1258,30 +1292,32 @@ def _finalize(self, names: Sequence[str]) -> None:
12581292 message = f"C3: missing stabilizer ({ operator_display_name (COHERENCE )} or { operator_display_name (SELF_ORGANIZATION )} ) - integral divergence (BOUNDEDNESS constraint)" ,
12591293 )
12601294
1261- # Self-organization block closure (structural time)
1262- # THOL closes automatically at sequence end - validates all captured subsequences
1295+ # Self-organization bifurcation window closure
1296+ # Empty window is valid (no bifurcation: ∂²EPI/∂t² ≤ τ)
1297+ # Non-empty window must contain valid sequence (bifurcation occurred)
12631298 if self ._open_thol :
1264- # Close all open THOL blocks from innermost to outermost
1299+ # Close all open THOL windows with their current content
12651300 while self ._thol_stack :
12661301 thol_start = self ._thol_stack .pop ()
1267- thol_subseq = self ._thol_subsequences [thol_start ]
1302+ window_content = self ._thol_subsequences [thol_start ]
1303+
1304+ # Empty window is valid (THOL without bifurcation)
1305+ if len (window_content ) == 0 :
1306+ continue # Valid empty window
12681307
1269- # Validate subsequence (allows empty THOL - no bifurcation case)
1270- if len (thol_subseq ) > 0 :
1271- try :
1272- self ._validate_thol_subsequence (
1273- thol_subseq ,
1274- thol_start ,
1275- len (names ) - 1 ,
1276- names [- 1 ] if names else ""
1277- )
1278- except SequenceSyntaxError as e :
1279- # Re-raise with THOL context
1280- raise SequenceSyntaxError (
1281- index = e .index ,
1282- token = e .token ,
1283- message = f"Invalid THOL subsequence (opened at position { thol_start } ): { e .message } "
1284- ) from e
1308+ # Non-empty window: validate as complete sequence
1309+ # If window was not auto-closed during parsing, check if valid at sequence end
1310+ try :
1311+ nested_automaton = _SequenceAutomaton ()
1312+ nested_automaton .run (window_content )
1313+ # Valid - window is complete
1314+ except SequenceSyntaxError as e :
1315+ # Invalid/incomplete window
1316+ raise SequenceSyntaxError (
1317+ index = len (names ) - 1 ,
1318+ token = names [- 1 ] if names else "" ,
1319+ message = f"Invalid { operator_display_name (SELF_ORGANIZATION )} bifurcation window (opened at position { thol_start } ): { e .message } "
1320+ ) from e
12851321
12861322 self ._open_thol = False
12871323
0 commit comments