I don't understand why this query do not terminate

It isn’t all that useful when one side of the relation is infinite, as is the case for removing duplicates.

I see this kind of relation (with some infinite parts) as partial building blocks, in this particular example, the infinite side of the relation could be somehow restrained (with length/2 for instance) and the relation becomes useful I think.

The only infinite call to length/2 is using two variables (or, at least a partial list). I’ve seen that being used to generate increasingly long lists that satisfy some condition. This is an example of a simple one-dimensional enumeration that still has some meaning (but is also a common reason for non-termination). Removing duplicates requires an N dimensional enumeration, where the number of dimensions is the number of unique elements. Mathematicians do not mind. Impatient computer scientists often do mind. If not, the users of their products do mind :slight_smile:

2 Likes

I see your point, I’d like to be able to evaluate computation cost as you do, it seems really powerful.
I think I haven’t been clear in my previous comment, what I meant was to use length/2 in conjunction of distinct/2 in order to make distinct/2 infinite side finite.

Like this

% ?- length(X,5), distinct(X,[1,2,3]).
%@ X = [1, 1, 1, 2, 3] ;
%@ X = [1, 1, 2, 2, 3] ;
%@ X = [1, 1, 2, 1, 3] ... 

Its nice to read what freeze/2 does.

It would (at least for me) be even nicer if the documentation would have a paradigmatic example, that shows how one real use case for freeze e.g. what use case caused the freeze predicate and its friends to be defined.

1 Like

It’s not the simplest code, but library(protobufs) uses freeze/2 and when/2 to get bidirectional predicates. (I was continuing the style of the original implementer; in the end, I think that was a mistake and many of the predicates should have been one-directional.)

I think that there were two origins of “freeze” – Prolog-II (called “geler”, because French) and MU-Prolog (also NU-Prolog). The latter used “wait” directives on predicates, which in some ways is cleaner, but also means you may need to write more predicates. If you look for papers by Lee Naish, you’ll probably find some decent references (possibly in the manual for NU-Prolog). e.g. Automating Control for Logic Programs by Lee Naish, 1985.

Note that constraints are a kind of “wait” – they cause a test to be delayed until its sufficiently instantiated. This can be nicely used to convert generate&test programs to test&generate – the tests “fire” as the possibilities are generated, potentially pruning a large part of the search space.