Prolog, find minimum in a list

It is common to use a so-called “lagged argument” to benefit from first-argument indexing: list_min([L|Ls], Min) :- list_min(Ls, L, Min). list_min([], Min, Min). list_min([L|Ls], Min0, Min) :- Min1 is min(L, Min0), list_min(Ls, Min1, Min). This pattern is called a fold (from the left), and foldl/4, which is available in recent SWI versions, lets you write … Read more

How to define (and name) the corresponding safe term comparison predicates in ISO Prolog?

iso_dif/2 is much simpler to implement than a comparison: The built-in \= operator is available You now exactly what arguments to provide to\= Definition Based on your comments, the safe comparison means that the order won’t change if variables in both subterms are instanciated. If we name the comparison lt, we have for example: lt(a(X), … Read more

GNU Prolog assert error

Use assertz/1 or asserta/1 instead. GNU-Prolog does not provide assert/1 because only asserta/1 and assertz/1 are defined in the standard. Note that while asserta/1 always had one clear interpretation meaning add the clause at the beginning, the meaning of assertz/1 was more difficult to resolve since “add a clause at the end” does not completely … Read more

Prolog getting head and tail of string

SWI-Prolog has several different representation of what you might call “strings”. List of character codes (Unicode); List of chars (one-letter atoms); Strings, which are “atomic” objects, and can be manipulated only with the built-in predicates for strings; And finally, of course, atoms. You should read the documentation, but for now, you have at least two … Read more

Recursive Prolog predicate for reverse / palindrome

Ad 1: It is impossible to define reverse/2 as a (directly edit thx to @repeat: tail) recursive predicate – unless you permit an auxiliary predicate. Ad 2: palindrome(X) :- reverse(X,X). But the easiest way is to define such predicates with DCGs: iseq([]) –> []. iseq([E|Es]) –> iseq(Es), [E]. reverse(Xs, Ys) :- phrase(iseq(Xs), Ys). palindrome(Xs) :- … Read more

PROLOG: Determining if elements in list are equal if order does not matter

As a starting point, let’s take the second implementation of equal_elements/2 by @CapelliC: equal_elements([], []). equal_elements([X|Xs], Ys) :- select(X, Ys, Zs), equal_elements(Xs, Zs). Above implementation leaves useless choicepoints for queries like this one: ?- equal_elements([1,2,3],[3,2,1]). true ; % succeeds, but leaves choicepoint false. What could we do? We could fix the efficiency issue by using … Read more

Implementing “last” in Prolog

Question 1: Prolog systems are not always able to decide whether or not a clause will apply prior to executing it. The precise circumstances are implementation dependent. That is, you cannot rely on that decision in general. Systems do improve here from release to release. Consider as the simplest case: ?- X = 1 ; … Read more