Prolog FAQ

Doing challenging things in elegant ways in Prolog.

Making a Domain

In the example Num in 1..10, the 1..10 is called the domain of the variable Num.

When you have a list of possible values like [1936, 1939, 1945], you cannot directly use that as a domain. The conversion process follows:

Allowed = [1936, 1939, 1945],
list_to_fdset(Allowed, FD_Allowed),
fdset_to_range(FD_Allowed, Range),

Num in Range.

The vocabulary is slightly confusing; the documentation refers to the domain of a variable, but the functions call that same quantity a range.

Actions on a list: maplist

The basic version of maplist runs a function on all of the items in a list. The result is true if all of the function calls (“goal applications”) are true. (Footnote: when lists are not the same length, do more research.)

Table = [Nationality, Aircraft, Deployed, Label],
maplist(all_distinct, Table)

Maplist can also be given more inputs, which are then all passed to the function “in parallel”. (All of first ones, all of the second ones, etc.)

The code below results in Zs being [13,26,59].

math(A,B,C) :- C #= A + B,
ex1(Zs) :-
    maplist(math, [10,20,50], [3,6,9], Zs).

Because Prolog is not just an imperative language, you can put variables anywhere. If you want to see solution sets, change the #= to #<

math(A,B,C) :- C #= A + B,
ex2(Ys) :-
    maplist(math, [10,20,50], Ys, [13,26,59]).

Inline Functions (Lambda)

Simple use:

maplist([Xs]>>(Xs ins 1..4), Table)

Lambdas in Prolog do not automatically capture variables from outside! You need to list the variables you want to capture in braces.

Domain = 1..10,
maplist({Domain}/[Xs]>>(Xs ins Domain),
        Table).

N statements are true

“Exactly one of a sequence of statements is true.” Make sure you have the boolean library CLP(B) loaded - it contains the logic constraint satisfier.

The code below shows how to use sat and card to get Want true values from a list of booleans. Card creates a cardinality constraint. Sat arranges to satisfy the constraint.

simple1(Want,N,Xs) :-
    Xs = [X1,X2],
    Xs ins 1..10,
    V1 #<==> (X1 #= 1),
    V2 #<==> (X2 #= N),
    sat(card([Want],[V1,V2])).
Last modified February 22, 2024: Prolog reference and fact sheet. (08586b3)