Is there an easy way to view "stack traces" with the interpreter?

Just a small redundant explanation concerning:

% NOTHING IS BROKEN. You will see scary red messages.
% THEY DO NOT EXIST ON MY WINDOWS MACHINE AT ALL.
% And nothing is broken. I checked. It all works. I don't know what's up.
% But it works on my computer, and you can even query the things SWISH
% says doesn't exist and they WILL exist. Okay?

Red predicates are entry points. That is predicates that are
not called by other predicates. But the analyzer that decides the
color, doesn’t understand what expand_term/2 does, and that

in fact trait/4 is indirectly called by has_trait/1, has_trait_type/2, etc..
Maybe red is a little bit too agressive color for the purpose of
an entry point. It has also a double meaning, if its red, and it is not the

head of a clause, but a goal of the body, it means missing definition
But also the same problem here, the analyzer cannot extrapolate what
term expansion will do. I don’t know whether there is some notebook

technique that could avoid both. Except you could try at the top of the file:

:- dynamic(asserted/1).

The color now changes from red to pink for body occurences. And it
also changes the operational semantic of the expanded predicates a little bit,
since dynamic might be differently compiled than static. I don’t know whether

there is a directive static/1 that would say, hey I will be expanded?

True. Best is to use modules. Then you can export your entry points, making it a lot easier to understand the code and they become bold and blue.

Well, the cross referencer does run term expansion if it can. So, it is wise to run the development tools while the code is loaded. This does not work for SWISH. Works fine for local development. If for some reason you frequently need to restart Prolog (due to side effects of running the program), I usually run two Prolog instances: one with the code loaded for editing and one to run the code.

Then there are some tricks such as if you want term expansion to generate clauses for e.g., p/4, use something like this, i.e., expanding the same predicate as it produces.

term_expansion(p(dummy, _, _, _), Clauses) :- ...

p(dummy,_,_,_).

If you really want, the library(prolog_colour) has hooks that allow you to make it understand what you are doing and (re-)define the style for identified fragments. An extensive example of this is in library(http/html_decl). Not worth the trouble for a simple program, but worth considering if you define some infrastructure you’ll be developing for an extensive period of time. You can also use that with SWISH, but only if you run your own server, so you can load these extensions.

Thanks, but I’m talking about something a little different, and I don’t care too much about the color red.

It has to do with these scary red messages: right here. They say my code doesn’t exist, then happily query from it.

Meanwhile, SWI-Prolog on Windows displays nothing of this sort.

Might be a SWISH issue. Can you post a link to the program on SWISH ?

1 Like

A popular technique is a kind of staging. Instead of using expansion,
one would have two Notebooks, one is the Notebook with the original
rules and a transpiler, and one is a Notebook with the transpiled rules,

and helper predicates. If I am not mistaken Alain Colmerauer already
proudly showed such a feature for his Prolog v0. You can turn an
expansion into a transpiler in that you rename your expansion rule

form term_expansion/2 to term_transpile/2, and then have something:

transpile(Out) :-
    tell(Out),
    clause(H, B),
    term_transpile((trait(X, P, V, Y) :- B), L),
    member(C, L),
    write(C), write('.'), nl,
    fail.
transpile(_) :-
    told.

?- transpile('out.pl').

But I don’t know whether SWISH offers upload or storage space.
I saw somewhere an example where Excel Sheets were uploaded?
Maybe SWI-Tinker could do it, and store it in Browser storage.

So the problem is out.pl will probably be a local file and you would do
it locally. If you install a local Notebooks server, you can possibly do
such stuff. But lets say I would want to use SWISH, does it have a

remotely a current working directory for each user?

Disclaimer: Maybe out.pl will be huge compared to original, because
of Metzlers trick. So not sure whether what I wrote is even a good idea
for the problem at hand.

The public version does not. If you run your own server you can do more, but the public version is fully stateless.

Yes, Tinker can do this. It offers a virtual filesystem from Emscripten and browser storage based persistency for part of that.

But then, this does not add anything new compared to using term expansion. Note that if term expansion requires more context, you can have one term expansion rule that simply asserts the terms read, mapping them to [] and then you expand end_of_file by translating all asserted terms and return a list of clauses (and/or directives). That is, for example, how CHR works in SWI-Prolog (while originally it was a transpiler).

Yeah, thats something that gets overlooked sometimes
even in the Datalog case. Take this example:

path(X, Y) :- path(X, Z), edge(Z, Y).
path(X, Y) :- edge(X, Y).

With loop detection but without some fixpoint iteration,
it would only compute path = edge. So stack traces/checking
for cycles, either with b_setval/2 or with term_expansion/2,

gives results, that have something missing. But I wonder
whether Prolog systems have some alternatives to the
above must in stock. I read CHR in this thread, can it solve

left recursion? Modern tabling does it via SLG resolution
(XSB, etc..), but it can be also done via OLD resolution (Picat, etc..).
On my side I was mentioning streaming computations,

basically bottom up methods, which would also solve the
problem by going from backward chaining to forward chaining,
trivially also solve left recursion.