Prologue: a bug from the global stack with what looks like ONE recursion level for me

I'm pretty rusty in the prologue, but I'm not sure why such things do not work:

frack(3). frack(X) :- frack(X-1). 

So, if I rate frack (4). from an interactive invitation with the above facts, I expect that it will not have to be infinitely recursive, since 4-1 = 3. But I get this error in SWI-Prolog:

 ERROR: Out of global stack 
+4
source share
4 answers

Try:

 ?- 4-1 = 3. false. 

Why? Because 4-1 = -(4, 1) , which is clearly not a number, but a composite term.

To learn about integers in Prolog, use , for example (using GNU Prolog or B-Prolog):

  |  ? - 4-1 # = X.

 X = 3

In SWI-Prolog, a graphical tracer can be useful for you to see what happens:

 ?- gtrace, frack(4). 

For more complex debugging, I recommend failure-slice , as shown in the false answer .

+5
source

This is the reason for this failure. Your request does not end because there is a failure-slice of your program that does not end:

  ? - frack (4).

 frack (3): - false .
 frack (X): -
    frack (X-1), false .

You can fix this only by changing something in the visible part. Three SO answers suggest using (is)/2 . But this will not remove the default! In fact, using (is)/2 results in essentially the same fragment:

  ? - frack (4).

 frack (3): - false .
 frack (X): -
    Y is X - 1,
    frack (Y), false .

At least frack(4) now doing well, but it will loop on the back track. You must change something in the visible part, for example, an X test to avoid failure. See for more details.

+5
source
 frack(X) :- frack(X-1). 

it should be

 frack(X) :- Y is X - 1, frack(Y). 

As you wrote it, an X-1 expression X-1 first level is combined with a variable X at the next level, never going over to the fact of frack(3) .

+3
source

Prolog does not do arithmetic unless you use the is statement:

 frack(X) :- X1 is X-1, frack(X1). 
+2
source

Source: https://habr.com/ru/post/1395781/


All Articles