Complexity of ISO Prolog predicates

tl;dr: No and no. Let’s start with sort/2 which ideally would need n ld(n) comparisons. Fine, but how long does one comparison take? Let’s try this out: tails(Es0, [Es0|Ess]) :- Es0 = [_|Es], tails(Es, Ess). tails([],[[]]). call_time(G,T) :- statistics(runtime,[T0|_]), G, statistics(runtime,[T1|_]), T is T1 – T0. | ?- between(12,15,I), N is 2^I, length(L,N),maplist(=(a),L), tails(L,LT), call_time(sort(LT,LTs), … Read more

Safer type tests in Prolog

The testing for types needs to distinguish itself from the traditional “type testing” built-ins that implicitly also test for a sufficient instantiation. So we effectively test only for sufficiently instantiated terms (si). And if they are not sufficiently instantiated, an appropriate error is issued. For a type nn, there is thus a type testing predicate … Read more

Einsteins Riddle Prolog

This site is devoted to solve such puzzles with CLP(FD). But the full power of CLP(FD) is overkill here: your assignment can be solved effectively searching the entire solution space when you have adequately described the constraints. The solution will be composed of 5 houses, where each attribute satisfy all constraints imposed by description. Be … Read more

Stack overflow in Prolog DCG grammar rule: how to handle large lists efficiently or lazily

As a general remark you will find more on SO about it under the name library(pio). Also the way to use it cleanly is rather: :- use_module(library(pio)). Your example is way too complex, so I will only consider a slightly simpler case, a newline separated list of numbers: nats([]) –> []. nats([N|Ns]) –> nat(N), newline, … Read more

Finding Unique Items in a List

You have been using cut and an unsafe form of negation. Both have to be used with extreme care. An immediate fix would be to guard your program against uses it is not designed for: unique(X, Xs) :- iwhen(ground(X+Xs), your_unique(X, Xs)). This uses iwhen/2 which is similar to when/2 except that it does not delay: … Read more

Prolog successor notation yields incomplete result and infinite loop

If you want to study termination properties in depth, programs using successor-arithmetics are an ideal study object: You know a priori what they should describe, so you can concentrate on the more technical details. You will need to understand several notions. Universal termination The easiest way to explain it, is to consider Goal, false. This … Read more

Delete vowels in a list

The following is based on the reification of term equality/inequality. First, we first define list_memberd_t/3, which behaves just like the memberd_truth/3 but has a different argument order: list_memberd_t([] ,_,false). list_memberd_t([Y|Ys],X,Truth) :- if_(X=Y, Truth=true, list_memberd_t(Ys,X,Truth)). list_memberd_truth(Xs,X,Truth) :- list_memberd_t(Xs,X,Truth). For the sake of brevity, let’s define memberd_t/3 based on list_memberd_t/3: memberd_t(X,Xs,Truth) :- list_memberd_t(Xs,X,Truth). As a parallel to … Read more