@@ -271,6 +271,10 @@ module KindPredicatesLog {
271271
272272 float getResultSize ( ) { result = this .getFloat ( "resultSize" ) }
273273
274+ Array getRA ( string ordering ) { result = this .getObject ( "ra" ) .getArray ( ordering ) }
275+
276+ string getAnOrdering ( ) { exists ( this .getRA ( result ) ) }
277+
274278 override string toString ( ) {
275279 if exists ( this .getPredicateName ( ) )
276280 then result = this .getPredicateName ( )
@@ -335,8 +339,12 @@ module KindPredicatesLog {
335339 raExpr .getLine ( ) = i
336340 }
337341
342+ Array getCounts ( ) { result = this .getArray ( "counts" ) }
343+
338344 float getCount ( int i ) { result = getRanked ( this .getArray ( "counts" ) , i ) }
339345
346+ Array getDuplicationPercentage ( ) { result = this .getArray ( "duplicationPercentages" ) }
347+
340348 float getDuplicationPercentage ( int i ) {
341349 result = getRanked ( this .getArray ( "duplicationPercentages" ) , i )
342350 }
@@ -374,6 +382,123 @@ module KindPredicatesLog {
374382 string getPosition ( ) { result = this .getString ( "position" ) }
375383
376384 Predicate getPredicate ( ) { result = getPredicateFromPosition ( this .getPosition ( ) ) }
385+
386+ /**
387+ * Gets the RA for this event. Unlike recursive predicates, a COMPUTE_SIMPLE
388+ * event only has one pipeline ordering (and it's named "pipeline").
389+ */
390+ PipeLine getPipeLine ( ) { result = this .getObject ( "ra" ) .getArray ( "pipeline" ) }
391+ }
392+
393+ /** Gets the `index`'th event that's evaluated by `recursive`. */
394+ private InLayer layerEventRank ( ComputeRecursive recursive , int index ) {
395+ result =
396+ rank [ index + 1 ] ( InLayer cand , int startline , string filepath |
397+ cand .getComputeRecursiveEvent ( ) = recursive and
398+ cand .hasLocationInfo ( filepath , startline , _, _, _)
399+ |
400+ cand order by filepath , startline
401+ )
402+ }
403+
404+ /**
405+ * Gets the first predicate that's evaluated in an iteration
406+ * of the SCC computation rooted at `recursive`.
407+ */
408+ private InLayer firstPredicate ( ComputeRecursive recursive ) {
409+ result = layerEventRank ( recursive , 0 )
410+ }
411+
412+ /**
413+ * Gets the last predicate that's evaluated in an iteration
414+ * of the SCC computation rooted at `recursive`.
415+ */
416+ private InLayer lastPredicate ( ComputeRecursive recursive ) {
417+ exists ( int n |
418+ result = layerEventRank ( recursive , n ) and
419+ not exists ( layerEventRank ( recursive , n + 1 ) )
420+ )
421+ }
422+
423+ /**
424+ * Holds if the predicate represented by `next` was evaluated after the
425+ * predicate represented by `prev` in the SCC computation rooted at `recursive`.
426+ */
427+ predicate successor ( ComputeRecursive recursive , InLayer prev , InLayer next ) {
428+ exists ( int index |
429+ layerEventRank ( recursive , index ) = prev and
430+ layerEventRank ( recursive , index + 1 ) = next
431+ )
432+ }
433+
434+ bindingset [ this ]
435+ signature class ResultSig ;
436+
437+ /**
438+ * A signature for generically traversing a SCC computation.
439+ */
440+ signature module Fold< ResultSig R> {
441+ /**
442+ * Gets the base case for the fold. That is, the initial value that
443+ * is produced from the first evaluation of the first IN_LAYER event
444+ * in the recursive evaluation.
445+ */
446+ bindingset [ run]
447+ R base ( PipeLineRun run ) ;
448+
449+ /**
450+ * Gets the recursive case for the fold. That is, `r` is the accumulation
451+ * of the previous evaluations, and `run` is the pipeline of the next IN_LAYER
452+ * event that is evaluated.
453+ */
454+ bindingset [ run, r]
455+ R fold ( PipeLineRun run , R r ) ;
456+ }
457+
458+ module Iterate< ResultSig R, Fold< R > F> {
459+ private R iterate ( ComputeRecursive recursive , int iteration , InLayer pred ) {
460+ // Case: The first iteration
461+ iteration = 0 and
462+ (
463+ // Subcase: The first predicate in the first iteration
464+ pred = firstPredicate ( recursive ) and
465+ result = F:: base ( pred .getPipelineRuns ( ) .getRun ( 0 ) )
466+ or
467+ // Subcase: The predicate has a predecessor
468+ exists ( InLayer pred0 , R r |
469+ successor ( recursive , pred0 , pred ) and
470+ r = iterate ( recursive , 0 , pred0 ) and
471+ result = F:: fold ( pred .getPipelineRuns ( ) .getRun ( 0 ) , r )
472+ )
473+ )
474+ or
475+ // Case: Not the first iteration
476+ iteration > 0 and
477+ (
478+ // Subcase: The first predicate in the iteration
479+ pred = firstPredicate ( recursive ) and
480+ exists ( InLayer last , R r |
481+ last = lastPredicate ( recursive ) and
482+ r = iterate ( recursive , iteration - 1 , last ) and
483+ result = F:: fold ( pred .getPipelineRuns ( ) .getRun ( iteration ) , r )
484+ )
485+ or
486+ // Subcase: The predicate has a predecessor in the same iteration
487+ exists ( InLayer pred0 , R r |
488+ successor ( recursive , pred0 , pred ) and
489+ r = iterate ( recursive , iteration , pred0 ) and
490+ result = F:: fold ( pred .getPipelineRuns ( ) .getRun ( iteration ) , r )
491+ )
492+ )
493+ }
494+
495+ R iterate ( ComputeRecursive recursive ) {
496+ exists ( int iteration , InLayer pred |
497+ pred = lastPredicate ( recursive ) and
498+ result = iterate ( recursive , iteration , pred ) and
499+ not exists ( iterate ( recursive , iteration + 1 , pred ) )
500+ )
501+ }
377502 }
378503
379504 class ComputeRecursive extends SummaryEvent {
@@ -382,6 +507,20 @@ module KindPredicatesLog {
382507
383508 class InLayer extends SummaryEvent {
384509 InLayer ( ) { evaluationStrategy = "IN_LAYER" }
510+
511+ string getMainHash ( ) { result = this .getString ( "mainHash" ) }
512+
513+ ComputeRecursive getComputeRecursiveEvent ( ) { result .getRAHash ( ) = this .getMainHash ( ) }
514+
515+ Array getPredicateIterationMillis ( ) { result = this .getArray ( "predicateIterationMillis" ) }
516+
517+ float getPredicateIterationMillis ( int i ) {
518+ result = getRanked ( this .getArray ( "predicateIterationMillis" ) , i )
519+ }
520+
521+ PipeLineRuns getPipelineRuns ( ) { result = this .getArray ( "pipelineRuns" ) }
522+
523+ float getDeltaSize ( int i ) { result = getRanked ( this .getArray ( "deltaSizes" ) , i ) }
385524 }
386525
387526 class ComputedExtensional extends SummaryEvent {
0 commit comments