Prolog process crash in qcompile/1

In a project I generate Prolog code from a custom language. Currently, nested expressions in that language create nested Prolog code, i.e., Prolog predicates with many levels of parentheses in the body.

At a certain depth of parentheses (around 1000-2000), the Prolog process crashes with Windows error code C00000FD, i.e., with a stack overflow. A trace analysis shows that the crash occurs in the qcompile/1 call. I use qcompile/1 to compile the generated code in the first run for faster loading in further runs. I can reproduce the crash with the Windows versions of SWI-Prolog 8.2.x, 8.4.x and 9.0.x. As a workaround I increased the process stack limit of the swipl.exe from 2 MB to 8 MB, which avoids the crash.

To really avoid these crashes, I think I need to change how the Prolog code is generated. So the question is, is the reducing of the levels of parentheses the only way to avoid stack overflows in qcompile/1?

As is, read/1 and variants are one of two places that are implemented as recursive C functions (the other is the compiler on certain constructs). On POSIX systems we do guard against stack overflows in these functions, turning them into normal Prolog exceptions.

Eventually this should be fixed, but that is not a simple task. read/1 is a nasty function with many cases of indirect recursion. Defining a nice stack engine for it is a serious rewrite. A possible alternative is to only keep the tokenizer in C and move the high level parser to Prolog. That too is quite a bit of work and complicates the bootstrapping of the system.

So yes, removing unnecessary parenthesis will help. If you do not use operators, but instead write e.g. is(A, +(1,2)), you do not need parenthesis to resolve ambiguities.

1 Like

Thanks. So I will check, how I can reduce the number of levels, for example by extracting common structures to own predicates.