@@ -264,6 +264,10 @@ module KindPredicatesLog {
264264
265265 float getResultSize ( ) { result = this .getFloat ( "resultSize" ) }
266266
267+ Array getRA ( string ordering ) { result = this .getObject ( "ra" ) .getArray ( ordering ) }
268+
269+ string getAnOrdering ( ) { exists ( this .getRA ( result ) ) }
270+
267271 override string toString ( ) {
268272 if exists ( this .getPredicateName ( ) )
269273 then result = this .getPredicateName ( )
@@ -325,12 +329,137 @@ module KindPredicatesLog {
325329 Predicate getPredicate ( ) { result = getPredicateFromPosition ( this .getPosition ( ) ) }
326330 }
327331
332+ /** Gets the `index`'th event that's evaluated by `recursive`. */
333+ private InLayer layerEventRank ( ComputeRecursive recursive , int index ) {
334+ result =
335+ rank [ index + 1 ] ( InLayer cand , int startline , string filepath |
336+ cand .getComputeRecursiveEvent ( ) = recursive and
337+ cand .hasLocationInfo ( filepath , startline , _, _, _)
338+ |
339+ cand order by filepath , startline
340+ )
341+ }
342+
343+ /**
344+ * Gets the first predicate that's evaluated in an iteration
345+ * of the SCC computation rooted at `recursive`.
346+ */
347+ private InLayer firstPredicate ( ComputeRecursive recursive ) {
348+ result = layerEventRank ( recursive , 0 )
349+ }
350+
351+ /**
352+ * Gets the last predicate that's evaluated in an iteration
353+ * of the SCC computation rooted at `recursive`.
354+ */
355+ private InLayer lastPredicate ( ComputeRecursive recursive ) {
356+ exists ( int n |
357+ result = layerEventRank ( recursive , n ) and
358+ not exists ( layerEventRank ( recursive , n + 1 ) )
359+ )
360+ }
361+
362+ /**
363+ * Holds if the predicate represented by `next` was evaluated after the
364+ * predicate represented by `prev` in the SCC computation rooted at `recursive`.
365+ */
366+ predicate successor ( ComputeRecursive recursive , InLayer prev , InLayer next ) {
367+ exists ( int index |
368+ layerEventRank ( recursive , index ) = prev and
369+ layerEventRank ( recursive , index + 1 ) = next
370+ )
371+ }
372+
373+ bindingset [ this ]
374+ signature class ResultSig ;
375+
376+ /**
377+ * A signature for generically traversing a SCC computation.
378+ */
379+ signature module Fold< ResultSig R> {
380+ /**
381+ * Gets the base case for the fold. That is, the initial value that
382+ * is produced from the first evaluation of the first IN_LAYER event
383+ * in the recursive evaluation.
384+ */
385+ bindingset [ run]
386+ R base ( PipeLineRun run ) ;
387+
388+ /**
389+ * Gets the recursive case for the fold. That is, `r` is the accumulation
390+ * of the previous evaluations, and `run` is the pipeline of the next IN_LAYER
391+ * event that is evaluated.
392+ */
393+ bindingset [ run, r]
394+ R fold ( PipeLineRun run , R r ) ;
395+ }
396+
397+ module Iterate< ResultSig R, Fold< R > F> {
398+ private R iterate ( ComputeRecursive recursive , int iteration , InLayer pred ) {
399+ // Case: The first iteration
400+ iteration = 0 and
401+ (
402+ // Subcase: The first predicate in the first iteration
403+ pred = firstPredicate ( recursive ) and
404+ result = F:: base ( pred .getPipelineRuns ( ) .getRun ( 0 ) )
405+ or
406+ // Subcase: The predicate has a predecessor
407+ exists ( InLayer pred0 , R r |
408+ successor ( recursive , pred0 , pred ) and
409+ r = iterate ( recursive , 0 , pred0 ) and
410+ result = F:: fold ( pred .getPipelineRuns ( ) .getRun ( 0 ) , r )
411+ )
412+ )
413+ or
414+ // Case: Not the first iteration
415+ iteration > 0 and
416+ (
417+ // Subcase: The first predicate in the iteration
418+ pred = firstPredicate ( recursive ) and
419+ exists ( InLayer last , R r |
420+ last = lastPredicate ( recursive ) and
421+ r = iterate ( recursive , iteration - 1 , last ) and
422+ result = F:: fold ( pred .getPipelineRuns ( ) .getRun ( iteration ) , r )
423+ )
424+ or
425+ // Subcase: The predicate has a predecessor in the same iteration
426+ exists ( InLayer pred0 , R r |
427+ successor ( recursive , pred0 , pred ) and
428+ r = iterate ( recursive , iteration , pred0 ) and
429+ result = F:: fold ( pred .getPipelineRuns ( ) .getRun ( iteration ) , r )
430+ )
431+ )
432+ }
433+
434+ R iterate ( ComputeRecursive recursive ) {
435+ exists ( int iteration , InLayer pred |
436+ pred = lastPredicate ( recursive ) and
437+ result = iterate ( recursive , iteration , pred ) and
438+ not exists ( iterate ( recursive , iteration + 1 , pred ) )
439+ )
440+ }
441+ }
442+
328443 class ComputeRecursive extends SummaryEvent {
329444 ComputeRecursive ( ) { evaluationStrategy = "COMPUTE_RECURSIVE" }
330445 }
331446
332447 class InLayer extends SummaryEvent {
333448 InLayer ( ) { evaluationStrategy = "IN_LAYER" }
449+
450+ string getMainHash ( ) { result = this .getString ( "mainHash" ) }
451+
452+ ComputeRecursive getComputeRecursiveEvent ( ) { result .getRAHash ( ) = this .getMainHash ( ) }
453+
454+ Array getPredicateIterationMillis ( ) { result = this .getArray ( "predicateIterationMillis" ) }
455+
456+ float getPredicateIterationMillis ( int i ) {
457+ result = getRanked ( this .getArray ( "predicateIterationMillis" ) , i )
458+ }
459+
460+ PipeLineRuns getPipelineRuns ( ) { result = this .getArray ( "pipelineRuns" ) }
461+
462+ float getDeltaSize ( int i ) { result = getRanked ( this .getArray ( "deltaSizes" ) , i ) }
334463 }
335464
336465 class ComputedExtensional extends SummaryEvent {
0 commit comments