Search code examples
prolog

Why this failed


I'm a beginner in Prolog after 40 years of imperative programming.

#!/usr/bin/swipl
:- use_module(library(clpfd)).

all_digits( [] ).
all_digits( [H|T] ) :-
   memberchk( H, [0,1,2,3,4,5,6,7,8,9] ),
   all_digits( T ).

:-
   is_list( A ),
   length( A, 3 ),
   all_digits( A ),
   halt( 0 ).

This program is in progress, I have another rules to add, but it already failed.

Why?

I expect 720 solutions: n!(n−p)! because each digit must be used only once.


Solution

  • Without using clpfd:

    uniq_digits_3(L) :-
        % Assemble list of [0, 1, ..., 9]
        numlist(0, 9, Digits),
        % Restrict length, so selects/2 knows when to stop
        length(L, 3),
        selects(L, Digits).
    
    selects([], _Ys).
    selects([X|Xs], Ys) :-
        % Take 1 element from Ys
        select(X, Ys, Ys0),
        % Loop with the remaining Ys0
        selects(Xs, Ys0).
    

    Result in swi-prolog:

    ?- bagof(L, uniq_digits_3(L), Ls), length(Ls, LsLen).
    Ls = [[0, 1, 2], [0, 1, 3], ...
    LsLen = 720.