@@ -254,17 +254,6 @@ class Trace extends TTrace {
254254 }
255255}
256256
257- /**
258- * Gets a string corresponding to the trace `t`.
259- */
260- string concretise ( Trace t ) {
261- t = Nil ( ) and result = ""
262- or
263- exists ( InputSymbol s1 , InputSymbol s2 , InputSymbol s3 , Trace rest | t = Step ( s1 , s2 , s3 , rest ) |
264- result = concretise ( rest ) + getAThreewayIntersect ( s1 , s2 , s3 )
265- )
266- }
267-
268257/**
269258 * Holds if there exists a transition from `r` to `q` in the product automaton.
270259 * Notice that the arguments are flipped, and thus the direction is backwards.
@@ -332,6 +321,39 @@ StateTuple getAnEndTuple(State pivot, State succ) {
332321 result = MkStateTuple ( pivot , succ , succ )
333322}
334323
324+ private class RelevantTrace extends Trace {
325+ RelevantTrace ( ) {
326+ exists ( State pivot , State succ , StateTuple q |
327+ isReachableFromStartTuple ( pivot , succ , q , this , _) and
328+ q = getAnEndTuple ( pivot , succ )
329+ )
330+ }
331+
332+ private Trace getSuffix ( int i ) {
333+ i = 0 and
334+ result = this
335+ or
336+ this .getSuffix ( i - 1 ) = Step ( _, _, _, result )
337+ }
338+
339+ private predicate hasTuple ( int i , InputSymbol s1 , InputSymbol s2 , InputSymbol s3 ) {
340+ this .getSuffix ( i ) = Step ( s1 , s2 , s3 , _)
341+ }
342+
343+ /** Gets a string corresponding to this trace. */
344+ // the pragma is needed for the case where `getAThreewayIntersect(s1, s2, s3)` has multiple values,
345+ // not for recursion
346+ language [ monotonicAggregates]
347+ string concretise ( ) {
348+ result =
349+ concat ( int i , InputSymbol s1 , InputSymbol s2 , InputSymbol s3 |
350+ this .hasTuple ( i , s1 , s2 , s3 )
351+ |
352+ getAThreewayIntersect ( s1 , s2 , s3 ) order by i desc
353+ )
354+ }
355+ }
356+
335357/**
336358 * Holds if matching repetitions of `pump` can:
337359 * 1) Transition from `pivot` back to `pivot`.
@@ -345,10 +367,10 @@ StateTuple getAnEndTuple(State pivot, State succ) {
345367 * available in the `hasReDoSResult` predicate.
346368 */
347369predicate isPumpable ( State pivot , State succ , string pump ) {
348- exists ( StateTuple q , Trace t |
370+ exists ( StateTuple q , RelevantTrace t |
349371 isReachableFromStartTuple ( pivot , succ , q , t , _) and
350372 q = getAnEndTuple ( pivot , succ ) and
351- pump = concretise ( t )
373+ pump = t . concretise ( )
352374 )
353375}
354376
0 commit comments