Compiler support for cyclic terms?

According to section 2.17 SWI-Prolog -- Manual :

“In addition, some built-ins recognise rational trees and raise an appropriate exception. Arithmetic evaluation belongs to this group. The compiler (asserta/1, etc.) also raises an exception. Future versions may support rational trees.”

Is there any real prospect of of compiler support?

My use case is support for a quasi-quoted syntax that can (optionally) produce a cyclic term. So I can use this qq syntax in queries but can’t in Prolog code which gets compiled.

So maybe not (just) a compiler issue. With

:- module(testQQ,[testQQ/4]).

:- quasi_quotation_syntax(testQQ).

testQQ(_Content,_Args,_Bindings,Result) :- Result = f(Result).

this:

?- G={|testQQ||_|}.
ERROR: Stack limit (1.0Gb) exceeded
ERROR:   Stack sizes: local: 0.8Gb, global: 0.2Gb, trail: 0Kb
ERROR:   Stack depth: 10,391,483, last-call: 50%, Choice points: 5
ERROR:   Possible non-terminating recursion:
ERROR:     [10,391,483] toplevel_variables:expand_args(1, 2, [length:1], <compound f/1>, <compound f/1>, _1848, _1850)
ERROR:     [10,391,481] toplevel_variables:expand_args(1, 2, [length:1], <compound f/1>, <compound f/1>, _1896, _1898)

I originally thought it might be a compiler issue since the quasi-quote was an argument in a clause head and I know you can’t assert such a clause with a cyclic term. But there may be more at play here.

Built-in, there is no hurry. You can quite easily check for a cyclic term though and call term_factorized/3 to create a non-cyclic version and stick the cycle unification at the start of the body. We could implement this in assert as a way to handle the exception, i.e. opportunistically assume the term is acyclic and do plan B otherwise.

Looks like the toplevel can’t deal with cyclic queries. As read_term/2 cannot produce these normally that doesn’t matter too much. A couple of things need to be fixed though. You’ll probably encounter similar problems for goal expansion. Pull requests welcome :slight_smile:

OK, this will do the trick to get around any issues I currently have.

Since I’m not in a position to use the new Mac fat binaries, this will be pretty low priority for me.