Collect all “minimum” solutions from a predicate

What is the idiomatic approach to this class of problems? Is there a way to simplify the problem? Many of the following remarks could be added to many programs here on SO. Imperative names Every time, you write an imperative name for something that is a relation you will reduce your understanding of relations. Not … Read more

reversible “binary to number” predicate

Use CLP(FD) constraints, for example: :- use_module(library(clpfd)). binary_number(Bs0, N) :- reverse(Bs0, Bs), foldl(binary_number_, Bs, 0-0, _-N). binary_number_(B, I0-N0, I-N) :- B in 0..1, N #= N0 + B*2^I0, I #= I0 + 1. Example queries: ?- binary_number([1,0,1], N). N = 5. ?- binary_number(Bs, 5). Bs = [1, 0, 1] . ?- binary_number(Bs, N). Bs = … Read more

Meaning of instantiation mode indicators in arguments of Prolog predicates

Those prefix operators, in this context, represent instantiation modes, i.e. they tell you which arguments should be variables or instantiated when calling the predicate. They also tell you if an argument will be (possibly further) instantiated by the call. They can also be used to tell you that an argument is going to be meta-interpreted … Read more

Knowing when to use cut in prolog

TL;DR: Don’t. The cut prunes Prolog’s search tree. That is, given a pure Prolog program without cut and the same program with cuts the only difference is that the program with cuts might spend less time in fruitless branches, and thus is more efficient ; might have fewer answers ; it might also terminate whereas … Read more

‘if’ in prolog?

Yes, there is such a control construct in ISO Prolog, called ->. You use it like this: ( condition -> then_clause ; else_clause ) Here is an example that uses a chain of else-if-clauses: ( X < 0 -> writeln(‘X is negative. That’s weird! Failing now.’), fail ; X =:= 0 -> writeln(‘X is zero.’) … Read more

Explanation of a Prolog algorithm to append two lists together

First, let’s translate the clauses into something more understandable: append([], List, List) :- !. can be written append([], List2, Result) :- Result = List2, !. and append([H|L1], List2, [H|L3]) :- append(L1, List2, L3). can be written append(List1, List2, Result) :- List1 = [Head1 | Tail1], Result = [HeadR | TailR], Head1 = HeadR, append(Tail1, List2, … Read more

Using \==/2 or dif/2

For elegance and didactic reasons alone, dif/2 is clearly preferable here and also in the vast majority of other cases, since as you already note “a lot of unnecessary unifications might take place” otherwise, and also because dif/2 is a pure and nicely declarative predicate that can be used in all directions and at any … Read more

Using a constrained variable with `length/2`

What’s probably more useful than a slightly less nondeterministic length/2 is a proper list-length constraint. You can find an ECLiPSe implementation of it here, called len/2. With this you get the following behaviour: ?- N :: 1..3, len(Xs, N). N = N{1 .. 3} Xs = [_431|_482] % note it must contain at least one … Read more