@@ -60,6 +60,9 @@ signature module UniversalFlowInput<LocationSig Location> {
6060 default predicate isExcludedFromNullAnalysis ( FlowNode n ) { none ( ) }
6161}
6262
63+ /**
64+ * Provides an implementation of universal flow using input `I`.
65+ */
6366module Make< LocationSig Location, UniversalFlowInput< Location > I> {
6467 private import I
6568
@@ -93,6 +96,7 @@ module Make<LocationSig Location, UniversalFlowInput<Location> I> {
9396
9497 private import Internal
9598
99+ /** Provides access to internal step relations. */
96100 module Internal {
97101 /**
98102 * Holds if data can flow from `n1` to `n2` in one step, `n1` is not necessarily
@@ -242,6 +246,10 @@ module Make<LocationSig Location, UniversalFlowInput<Location> I> {
242246 default predicate barrier ( FlowNode n ) { none ( ) }
243247 }
244248
249+ /**
250+ * Calculates a (nullary) property using universal flow given a base case
251+ * relation.
252+ */
245253 module FlowNullary< NullaryPropertySig P> {
246254 private module Propagation implements PropPropagation {
247255 class Prop = Unit ;
@@ -251,6 +259,10 @@ module Make<LocationSig Location, UniversalFlowInput<Location> I> {
251259 predicate supportsProp = candProp / 2 ;
252260 }
253261
262+ /**
263+ * Holds if all flow reaching `n` originates from nodes in
264+ * `hasPropertyBase`.
265+ */
254266 predicate hasProperty ( FlowNode n ) {
255267 P:: hasPropertyBase ( n )
256268 or
@@ -283,6 +295,10 @@ module Make<LocationSig Location, UniversalFlowInput<Location> I> {
283295 default predicate barrier ( FlowNode n ) { none ( ) }
284296 }
285297
298+ /**
299+ * Calculates a unary property using universal flow given a base case
300+ * relation.
301+ */
286302 module Flow< PropertySig P> {
287303 private module Propagation implements PropPropagation {
288304 class Prop = P:: Prop ;
@@ -296,8 +312,9 @@ module Make<LocationSig Location, UniversalFlowInput<Location> I> {
296312 }
297313
298314 /**
299- * Holds if the runtime type of `n` is exactly `t` and if this bound is a
300- * non-trivial lower bound, that is, `t` has a subtype.
315+ * Holds if all flow reaching `n` originates from nodes in
316+ * `hasPropertyBase`. The property `t` is taken from one of those origins
317+ * such that all other origins imply `t`.
301318 */
302319 predicate hasProperty ( FlowNode n , P:: Prop t ) {
303320 P:: hasPropertyBase ( n , t )
@@ -307,13 +324,25 @@ module Make<LocationSig Location, UniversalFlowInput<Location> I> {
307324 exists ( FlowNode mid | hasProperty ( mid , t ) and uniqStepNotNull ( mid , n ) )
308325 or
309326 // The following is an optimized version of
310- // `forex(FlowNode mid | joinStepNotNull(mid, n) | hasPropery(mid, t))`
327+ // ```
328+ // exists(FlowNode mid | joinStepNotNull(mid, n) | hasPropery(mid, t)) and
329+ // forall(FlowNode mid | joinStepNotNull(mid, n) | hasPropery(mid, _)) and
330+ // forall(FlowNode mid, P::Prop t0 | joinStepNotNull(mid, n) and hasPropery(mid, t0) |
331+ // P::propImplies(t0, t)
332+ // )
333+ // ```
311334 ForAll< FlowNode , RankedJoinStep , Propagation > :: flowJoin ( n , t )
312335 or
313336 exists ( FlowScc scc |
314337 sccRepr ( n , scc ) and
315338 // Optimized version of
316- // `forex(FlowNode mid | sccJoinStepNotNull(mid, scc) | hasPropery(mid, t))`
339+ // ```
340+ // exists(FlowNode mid | sccJoinStepNotNull(mid, n) | hasPropery(mid, t)) and
341+ // forall(FlowNode mid | sccJoinStepNotNull(mid, n) | hasPropery(mid, _)) and
342+ // forall(FlowNode mid, P::Prop t0 | sccJoinStepNotNull(mid, n) and hasPropery(mid, t0) |
343+ // P::propImplies(t0, t)
344+ // )
345+ // ```
317346 ForAll< FlowScc , RankedSccJoinStep , Propagation > :: flowJoin ( scc , t )
318347 )
319348 )
0 commit comments