"No permission to append findall-bag"

Hi!

I’m trying out tabling, but I get an unintelligible error:

ERROR: -g main: No permission to append findall-bag `[...]' (continuation in findall/3 generator?)
ERROR: In:
ERROR:   [13] throw(error(permission_error(append,'findall-bag',...),context(...,'continuation in findall/3 generator?')))
ERROR:   [12] '$tabling':start_tabling(user:auswerten(jm,_2980),user:'auswerten tabled'(jm,_2992)) at /usr/lib/swi-prolog/boot/tabling.pl:98
ERROR:   [10] auswerten1(jm,_3018) at /home/v/src/tt/tt2.pl:207
ERROR:    [9] main at /home/v/src/tt/tt2.pl:80
ERROR:    [8] catch(user:main,error(permission_error(append,'findall-bag',...),context(...,'continuation in findall/3 generator?')),'$toplevel':true) at /usr/lib/swi-prolog/boot/init.pl:386
ERROR:    [7] catch_with_backtrace(user:main,error(permission_error(append,'findall-bag',...),context(...,'continuation in findall/3 generator?')),'$toplevel':true) at /usr/lib/swi-prolog/boot/init.pl:436
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

I’ve no idea what that means. Does someone have a hint?

Cheers,
Volker

That is a complicated way to tell that you have a recursive tabled loop through findall/3. That is not possible.

Well, maybe it is different. If you are on 8.0.x tabling and findall do not combine at all. Using a not-too-old 8.1.x tabling and findall/3 work fine, provided that the goal called by findall does not (indirectly) call any tabled variant that calls the findall/3.

Does that make sense?

Yes, I am. I’ll install the current development version.

Somewhat. I don’t understand the “not (indirectly) call any tabled variant” part. Call a tabled variant of what?

Bye,
Volker

Tabling is (by default) based on variants (see =@=/2). The problem arises when variant V calls findall/3, which in turn calls V. For example:

p(X,Y) :-
      findall(Z, p(X,Z), Zs).

If we call this is p(1, X), the findall/3 goal is p(1,Z) and as X and Z are unbound, this is a variant. Now we get a child call of findall/3 being dependent on a caller of findall/3. That leads to this error.

1 Like

That’s what I have here… Also, I’ve tried SWI-Prolog version 8.1.21. It’s the same.

Thanks for the explanation.

Volker

Imagine what needs to happen. The findall goal needs to complete before we can create the list. I don’t see how this should work …

Note that the same applies the ! and ->, although here you currently get incomplete results. So this doesn’t work:

p(X) :- ( p(X) -> x; y ).

If the if-then-else has no dependency on any parent goal all goes fine as its tabling component is completed before the → commit happens.

I’ve rearranged my program, and now it works. I’m building a sort of miniature expert system, and am using tabling to accomplish termination. Thanks for your help!

Bye,
Volker