Project

Profile

Help

limitation of the number of recursion

Added by Anonymous over 18 years ago

Legacy ID: #3870864 Legacy Poster: tjsh (tjsh)

When I excuted my xquery file by saxon8.7.3j, some errors appeared as follow: "Too many nested function calls. May be due to infinite recursion.Query processing failed: Run-time errors were reported" I know I have used many nested function which is inavoidable due to the limitation of xquery. So I was wondering that if there anything like "constant value" in saxonica that could be used to control the nest number of function? If so, how I modify it by myself? Ohtherwise, would anybody give me some suggestions about this problem?


Replies (9)

Please register to reply

RE: limitation of the number of recursion - Added by Anonymous over 18 years ago

Legacy ID: #3871074 Legacy Poster: Michael Kay (mhkay)

This limit is imposed by the size of the Java stack, which unfortunately is not configurable. The best bet is to try and write your function to be tail-recursive (so that calling itself is the last thing it does). In this case Saxon will make the recursive call reuse the stackframe of the caller, which in effect gives you an infinite recursion depth. The other approach is to rewrite a head-tail recursion as a divide-and-conquer recursion. Instead of processing the head element and then calling yourself to process the tail, write your recursion so that you call yourself twice, once to process the first half of the input and once to process the second half. Of course not all problems lend themselves to this treatment.

RE: limitation of the number of recursion - Added by Anonymous over 18 years ago

Legacy ID: #3872717 Legacy Poster: tjsh (tjsh)

Thank you for your replay, I have some another question to bother you: Saxonica can either run XQuery from the Command Line or invoke XQuery from an application. So will these two ways have the same processing performance? And if I use Java and xml parser like JDOM to implement the same function that XQuery does by Saxonica, which one is more effective? Thanks again.

RE: limitation of the number of recursion - Added by Anonymous over 18 years ago

Legacy ID: #3872966 Legacy Poster: Michael Kay (mhkay)

On the first question, there is a significant overhead every time you start up the Java VM. So in production applications, it is almost always best to invoke the query processor from a continuously-running application, rather than from the command line. On the other hand, if you are running a single query that takes 30 seconds or more, the overhead of running from the command line won't be noticeable. On the second question, it depends on your definition of "effective", and it depends how good your coding skills in the two languages are. Generally speaking, you can get better performance using a lower-level language provided that you have enough time and skill to do the development; but given limited time and effort, you should use the highest-level language available (which in this case means XSLT or XQuery).

RE: limitation of the number of recursion - Added by Anonymous about 17 years ago

Legacy ID: #4498560 Legacy Poster: Igor Karp (ikarp)

  1. Has anything changed with 8.9J ? 2. Shall this behavior be affected by -Xss java option ? 3. What might prevent tail recursion from kicking in ? in my case recursive functions are ok with size of input like 300-600 but break at around 3000 just in case this might help here are two functions (remove overlaps and gaps): <xsl:function name="ik:clean1"> <xsl:param name="broadcasts"/> <xsl:choose> <xsl:when test="count($broadcasts) le 1"> <xsl:copy-of select="$broadcasts"/> </xsl:when> <xsl:when test="$broadcasts[2]/gmt_start_date_time lt $broadcasts[1]/gmt_end_date_time"> <xsl:copy-of select="$broadcasts[1]"/> <xsl:copy-of select="ik:clean1($broadcasts[position() gt 2])"/> </xsl:when> <xsl:otherwise> <xsl:copy-of select="$broadcasts[1]"/> <xsl:copy-of select="ik:clean1($broadcasts[position() gt 1])"/> </xsl:otherwise> </xsl:choose> </xsl:function> <xsl:function name="ik:clean2"> <xsl:param name="broadcasts"/> <xsl:choose> <xsl:when test="count($broadcasts) le 1"> <xsl:copy-of select="$broadcasts"/> </xsl:when> <xsl:otherwise> <xsl:copy-of select="$broadcasts[1]"/> <xsl:if test="$broadcasts[2]/gmt_start_date_time gt $broadcasts[1]/gmt_end_date_time"> <broadcast id="{$broadcasts[1]/@id}G" language_6392t="{$broadcasts[1]/@language_6392t}"> <title>Programmpause</title> <gmt_start_date_time><xsl:value-of select="$broadcasts[1]/gmt_end_date_time"/></gmt_start_date_time> <gmt_end_date_time><xsl:value-of select="$broadcasts[2]/gmt_start_date_time"/></gmt_end_date_time> </broadcast> </xsl:if> <xsl:copy-of select="ik:clean2($broadcasts[position() gt 1])"/> </xsl:otherwise> </xsl:choose> </xsl:function> they are called like this: <xsl:apply-templates select="ik:clean2(ik:clean1($broadcasts))"/> or <xsl:apply-templates select="ik:clean2($broadcasts)"/> or <xsl:apply-templates select="ik:clean1($broadcasts)"/> each of these calls fails with big input size with net.sf.saxon.trans.DynamicError: Too many nested function calls. May be due to infinite recursion.

RE: limitation of the number of recursion - Added by Anonymous about 17 years ago

Legacy ID: #4498571 Legacy Poster: Michael Kay (mhkay)

Dear ikarp: It's best to start a new thread for a new topic on this forum, otherwise things get very difficult to follow. I can't see any reason why your code isn't tail-recursive. Please (a) make sure you are using Saxon 8.9.0.4, and (b) try to produce a self-contained example that demonstrates the problem. I'll look at it when I get back from vacation. (A good place to post it, because it allows attachments, is the support-requests tracker).

RE: limitation of the number of recursion - Added by Anonymous about 17 years ago

Legacy ID: #4636822 Legacy Poster: Joseph Thomas-Kerr (jak09)

I am getting this same error running an XSLT2 stylesheet with Saxon 9. First up, I think that it would be good to improve the precision of the error message since in my case it is not "Functions" that are recursive but rather templates. I do call some user-defined functions in my stylesheet, and the line-number reported by the error calls one of my functions, but none of my functions are recursive. What is highly recursive is my templates. I chain a several of them together using next match, giving something like the following. <xsl:template match="nal_unit" priority="10"> <!-- do some stuff --> <xsl:next-match/> </xsl:template> <xsl:template match="*" priority="-10"> <xsl:apply-templates select="following::nal_unit[1]"/> </xsl:template> I am running this over a document containing around 10 000 nal_units. This is actually tail-recursive, but I guess it is not picked up by your optimizer (understandably, since in actuality my stylesheet has several more templates in between these two and in general this recursive behaviour could be arbitrarily indirect). The whole reason I am processing the document like this rather than using the depth-first pattern normally used in XSLT is that I need to pass a number of variables from one nal_unit template to the next. Because XSLT variables are immutable I cannot see another way to pass the variables from nal_unit[n] to nal_unit[n+1]. (But maybe I'm just not seeing it - I'd be happy to be proved wrong). Regards, Joe.

RE: limitation of the number of recursion - Added by Anonymous about 17 years ago

Legacy ID: #4637152 Legacy Poster: Michael Kay (mhkay)

Actually the problem with the error message is that it is too precise. It's making guesses about the cause of the problem on the basis of insufficient evidence. The only way to make the message more accurate is to make it less precise, and I'm reluctant to do that. It's a fine call, but in general with a condition like "stack overflow" I prefer where possible to give a message that hints at the most likely cause, on the basis that this will help users more often than it hinders them. I do try and phrase the message in such a way that it's clearly speculating on the cause of the problem. Without seeing your actual code I can't comment on why tail call optimization isn't kicking in. And beyond that, I'm not sure what you are asking for?

RE: limitation of the number of recursion - Added by Anonymous about 17 years ago

Legacy ID: #4637318 Legacy Poster: Joseph Thomas-Kerr (jak09)

Oh, sorry, I didn't provide enough background. I have a large document <h264> <nal_unit/><!--nb these aren't actually empty, they all have child content--> <nal_unit/> <!-- ...x10000...--> <nal_unit/> </h264> I want a template (or actually several templates) that process each nal_unit. But nal_unit[n] needs to know about the results of some processing done on nal_unit[n-1] which in turn is based on nal_unit[n-2] and so on. Normally, I would have a template like this: <xsl:template match="h264"> <!--...--> <xsl:apply-templates/> </xsl:template> However, this does not give me any way to pass data from the template that processes nal_unit[n-1] to the template that processes nal_unit[n]. So, instead, I pass from one nal_unit to the next using the following:: axis (as shown in my previous post). Then I can pass my computation from one to the next via parameters. This is fine, except that my document is very large and this recursion appears to exhaust the stack. I could switch it around and run a function that iterates backward along the preceding:: axis to compute my variables, but this has the same recursion-depth issues and would also be O(n^2). So my question is, given that XSLT variables are immutable, is there a way to pass parameters from the nal_unit[n-1] invocation to the nal_unit[n] invocation without calling the latter directly from the former? Regards, Joe.

RE: limitation of the number of recursion - Added by Anonymous about 17 years ago

Legacy ID: #4637557 Legacy Poster: Michael Kay (mhkay)

Your approach looks broadly correct except that you should be using the following-sibling axis rather than the following axis; and there is something in your coding that means the call is not being treated as tail-recursive, but I can't tell you what this is without seeing your code.

    (1-9/9)

    Please register to reply