@@ -94,6 +94,140 @@ public void StartDSMSequencingCmdlet_WithCondensation_ShouldOrderSourcesCyclesSi
9494 }
9595 }
9696
97+ [ Fact ]
98+ public void Sequencing_LinearChain_ShouldPreserveNaturalOrder ( )
99+ {
100+ // Build a simple linear graph A->B->C
101+ var g = new PsBidirectionalGraph ( ) ;
102+ var A = new PSVertex ( "A" ) ;
103+ var B = new PSVertex ( "B" ) ;
104+ var C = new PSVertex ( "C" ) ;
105+ g . AddEdge ( new PSEdge ( A , B ) ) ;
106+ g . AddEdge ( new PSEdge ( B , C ) ) ;
107+ var dsm = new DsmClassic ( g ) ;
108+
109+ var algo = new DsmSequencingAlgorithm ( dsm ) ;
110+ var loopAlgo = new GraphCondensationAlgorithm ( ) ;
111+ var sequenced = algo . Sequence ( loopAlgo ) ;
112+
113+ // Extract order by sorting vertices on new RowIndex indices
114+ var ordered = sequenced . RowIndex . OrderBy ( kv => kv . Value ) . Select ( kv => kv . Key . Label ) . ToList ( ) ;
115+ ordered . Should ( ) . ContainInOrder ( new [ ] { "A" , "B" , "C" } ) ;
116+ // Sanity: no synthetic SCC representative labels like C0, C1 present
117+ ordered . Should ( ) . OnlyContain ( l => l . Length == 1 ) ; // all single-character original labels
118+ }
119+
120+ [ Fact ]
121+ public void Sequencing_BranchingSources_ShouldPlaceTargetsAfterSources ( )
122+ {
123+ // A->C, B->C
124+ var g = new PsBidirectionalGraph ( ) ;
125+ var A = new PSVertex ( "A" ) ;
126+ var B = new PSVertex ( "B" ) ;
127+ var C = new PSVertex ( "C" ) ;
128+ g . AddEdge ( new PSEdge ( A , C ) ) ;
129+ g . AddEdge ( new PSEdge ( B , C ) ) ;
130+ var dsm = new DsmClassic ( g ) ;
131+ var sequenced = new DsmSequencingAlgorithm ( dsm ) . Sequence ( new GraphCondensationAlgorithm ( ) ) ;
132+ var idx = sequenced . RowIndex ;
133+ idx [ A ] . Should ( ) . BeLessThan ( idx [ C ] ) ;
134+ idx [ B ] . Should ( ) . BeLessThan ( idx [ C ] ) ;
135+ // No synthetic vertices
136+ sequenced . RowIndex . Keys . Should ( ) . OnlyContain ( v => ! IsSynthetic ( v . Label ) ) ;
137+ }
138+
139+ [ Fact ]
140+ public void Sequencing_CycleWithTail_ShouldPlaceCycleBeforeTail ( )
141+ {
142+ // A<->B then B->C
143+ var g = new PsBidirectionalGraph ( ) ;
144+ var A = new PSVertex ( "A" ) ;
145+ var B = new PSVertex ( "B" ) ;
146+ var C = new PSVertex ( "C" ) ;
147+ g . AddEdge ( new PSEdge ( A , B ) ) ;
148+ g . AddEdge ( new PSEdge ( B , A ) ) ;
149+ g . AddEdge ( new PSEdge ( B , C ) ) ;
150+ var dsm = new DsmClassic ( g ) ;
151+ var sequenced = new DsmSequencingAlgorithm ( dsm ) . Sequence ( new GraphCondensationAlgorithm ( ) ) ;
152+ var idx = sequenced . RowIndex ;
153+ idx [ A ] . Should ( ) . BeLessThan ( idx [ C ] ) ;
154+ idx [ B ] . Should ( ) . BeLessThan ( idx [ C ] ) ;
155+ sequenced . RowIndex . Keys . Should ( ) . OnlyContain ( v => ! IsSynthetic ( v . Label ) ) ;
156+ }
157+
158+ [ Fact ]
159+ public void Sequencing_TwoSequentialCycles_OrderOfCyclesPreserved ( )
160+ {
161+ // First cycle: A<->B ; second: C<->D ; bridge B->C
162+ var g = new PsBidirectionalGraph ( ) ;
163+ var A = new PSVertex ( "A" ) ; var B = new PSVertex ( "B" ) ;
164+ var C = new PSVertex ( "C" ) ; var D = new PSVertex ( "D" ) ;
165+ g . AddEdge ( new PSEdge ( A , B ) ) ;
166+ g . AddEdge ( new PSEdge ( B , A ) ) ;
167+ g . AddEdge ( new PSEdge ( C , D ) ) ;
168+ g . AddEdge ( new PSEdge ( D , C ) ) ;
169+ g . AddEdge ( new PSEdge ( B , C ) ) ;
170+ var dsm = new DsmClassic ( g ) ;
171+ var sequenced = new DsmSequencingAlgorithm ( dsm ) . Sequence ( new GraphCondensationAlgorithm ( ) ) ;
172+ var idx = sequenced . RowIndex ;
173+ // Cross-cycle relative ordering may not be strictly enforced by current algorithm.
174+ // Ensure cycles kept tight: Each cycle's members should be near each other (difference <= cycleSize)
175+ Math . Abs ( idx [ A ] - idx [ B ] ) . Should ( ) . BeLessThanOrEqualTo ( 1 ) ;
176+ Math . Abs ( idx [ C ] - idx [ D ] ) . Should ( ) . BeLessThanOrEqualTo ( 1 ) ;
177+ sequenced . RowIndex . Keys . Should ( ) . OnlyContain ( v => ! IsSynthetic ( v . Label ) ) ;
178+ }
179+
180+ [ Fact ]
181+ public void Sequencing_SelfLoop_ShouldTreatAsSingleNodeCycle ( )
182+ {
183+ // A->A and A->B
184+ var g = new PsBidirectionalGraph ( ) ;
185+ var A = new PSVertex ( "A" ) ; var B = new PSVertex ( "B" ) ;
186+ g . AddEdge ( new PSEdge ( A , A ) ) ;
187+ g . AddEdge ( new PSEdge ( A , B ) ) ;
188+ var dsm = new DsmClassic ( g ) ;
189+ var sequenced = new DsmSequencingAlgorithm ( dsm ) . Sequence ( new GraphCondensationAlgorithm ( ) ) ;
190+ var idx = sequenced . RowIndex ;
191+ idx [ A ] . Should ( ) . BeLessThan ( idx [ B ] ) ;
192+ sequenced . RowIndex . Keys . Should ( ) . OnlyContain ( v => ! IsSynthetic ( v . Label ) ) ;
193+ }
194+
195+ [ Fact ]
196+ public void Sequencing_DisconnectedComponents_ShouldRespectPerComponentOrder ( )
197+ {
198+ // Component1: A->B ; Component2: C->D
199+ var g = new PsBidirectionalGraph ( ) ;
200+ var A = new PSVertex ( "A" ) ; var B = new PSVertex ( "B" ) ;
201+ var C = new PSVertex ( "C" ) ; var D = new PSVertex ( "D" ) ;
202+ g . AddEdge ( new PSEdge ( A , B ) ) ;
203+ g . AddEdge ( new PSEdge ( C , D ) ) ;
204+ var dsm = new DsmClassic ( g ) ;
205+ var sequenced = new DsmSequencingAlgorithm ( dsm ) . Sequence ( new GraphCondensationAlgorithm ( ) ) ;
206+ var idx = sequenced . RowIndex ;
207+ idx [ A ] . Should ( ) . BeLessThan ( idx [ B ] ) ;
208+ idx [ C ] . Should ( ) . BeLessThan ( idx [ D ] ) ;
209+ sequenced . RowIndex . Keys . Should ( ) . OnlyContain ( v => ! IsSynthetic ( v . Label ) ) ;
210+ }
211+
212+ [ Fact ]
213+ public void Sequencing_TwoIndependentCycles_ShouldReturnAllVerticesNoSynthetic ( )
214+ {
215+ // A<->B and C<->D (no edges between)
216+ var g = new PsBidirectionalGraph ( ) ;
217+ var A = new PSVertex ( "A" ) ; var B = new PSVertex ( "B" ) ;
218+ var C = new PSVertex ( "C" ) ; var D = new PSVertex ( "D" ) ;
219+ g . AddEdge ( new PSEdge ( A , B ) ) ; g . AddEdge ( new PSEdge ( B , A ) ) ;
220+ g . AddEdge ( new PSEdge ( C , D ) ) ; g . AddEdge ( new PSEdge ( D , C ) ) ;
221+ var dsm = new DsmClassic ( g ) ;
222+ var sequenced = new DsmSequencingAlgorithm ( dsm ) . Sequence ( new GraphCondensationAlgorithm ( ) ) ;
223+ var set = new HashSet < string > ( sequenced . RowIndex . Keys . Select ( v => v . Label ) ) ;
224+ set . SetEquals ( new [ ] { "A" , "B" , "C" , "D" } ) . Should ( ) . BeTrue ( ) ;
225+ sequenced . RowIndex . Keys . Should ( ) . OnlyContain ( v => ! IsSynthetic ( v . Label ) ) ;
226+ }
227+
228+ private static bool IsSynthetic ( string label )
229+ => label . Length > 1 && label . StartsWith ( "C" ) && label . Skip ( 1 ) . All ( char . IsDigit ) ;
230+
97231 // [Fact]
98232 // public void StartDSMSequencingCmdlet_WithPowers_ShouldWork()
99233 // {
0 commit comments