-
Hi, I'm trying to follow the depth query specified on this page. import tutorial
int depth(Person p) {
if not exists(p.getAParent())
then result = 0
else result = 1 + max(Person g | g = p.getAParent() | depth(g))
}
from Person p
select p, depth(p) When I try to implement a similar "depth" function for the tutorial, I get the "Non-monotonic recursion: ..." error. Is there something I'm not understanding about the Node depth example? Why is that valid but my nearly identical implementation of that using the Person class in the tutorial not valid? Thanks |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
You need to add the Why? As set out in https://codeql.github.com/docs/ql-language-reference/expressions/#recursive-monotonic-aggregates, without the monotonic-aggregate semantics, on the second iteration of the algorithm the node With the |
Beta Was this translation helpful? Give feedback.
You need to add the
language[monotonicAggregates]
modifier to theint depth(...)
predicate.Why? As set out in https://codeql.github.com/docs/ql-language-reference/expressions/#recursive-monotonic-aggregates, without the monotonic-aggregate semantics, on the second iteration of the algorithm the node
a
would be assigned a depth of 1, because its childb
is known to have depth 0 and its childc
hasn't been assigned a depth yet. Then on the third iteration it would be necessary to revise the depth of nodea
to 2 (and presumably to revise any parents ofa
that would get transient wrong answers). This isn't compatible with CodeQL's approach to recursion, which requires that the result set gro…