Search code examples
prologconstraint-programmingclpfd

Constraining domain for variable through list


I have a list defined in one part of my program as

people([tom,betty,sue,fred,charles,chay])

I would like to constraint a variable to be N values in this domain. Something like :

setup(GroupCount) :-
    length(Group, GroupCount),
    people(X),
    Group :: X,
    all_different(Group),
    <other predicates>.

Currently, Prolog complains "calling undefined procedure Group :: [....] in eclipse. Abort"

I have looked through the SWI-Prolog documentation for lib(clpfd) and lib(lists), and elsewhere, but cannot find a suitable way to do so. Any clues?


Solution

  • From your error message I infer that you are using ECLiPSe, so you might want to refer to ECLiPSe's documentation rather than SWI-Prolog's ;)

    Most finite-domain constraint solver implementation restrict themselves to integer domains, so you would have to encode your people names as integers. However, ECLiPSe does provide a minimalist solver for symbolic domains, which you could use for your first experiments:

    :- lib(sd).    % load symbolic finite-domain solver
    
    people([tom,betty,sue,fred,charles,chay]).
    
    setup(GroupCount, Group) :-
        length(Group, GroupCount),
        people(X),
        Group &:: X,
        alldifferent(Group),
        labeling(Group).
    

    which works as follows

    ?- setup(3, G).
    G = [betty, charles, chay]
    Yes (0.00s cpu, solution 1, maybe more)
    G = [betty, charles, fred]
    Yes (0.00s cpu, solution 2, maybe more)
    ...
    

    For further work you probably want to switch to library(ic) which works over integer/real domains (instead of symbols) but is more feature-rich.