Search code examples
prologconstraintssicstus-prologclpfd

Using in_set/2 Constraint


I am trying to use constrain X to not being a value in a list.

From the SICStus Prolog manual:

?X in_set +FDSet 

I can't figure out how to convert a list to a FDSet, though. I have a list of integers [2,3,8,9] and I want to constrain the domain of variable X to not being in that list. How do I do that? Thanks.


Solution

  • Judging from the documentation, what about list_to_fdset/2? You can translate to an FDSet, then build its complement, then post in_set/2. If your version does not have list_to_fdset/2, you can easily convert the list to a normal domain expression, and then post a negated in/2 constraint. In your example, you would then post:

    #\ X in {2}\/{3}\/{8}\/{9}
    

    and you only have to describe the relation between a list and a domain expression consisting of singletons, which is easy:

    list_domain([I|Is], Dom) :-
            foldl(integer_domain_, Is, {I}, Dom).
    
    integer_domain_(I, D0, D0 \/ {I}).
    

    Example queries:

    ?- list_domain([1,2,3], Dom).
    Dom = {1}\/{2}\/{3}.
    
    ?- list_domain([1,2,3], Dom), X in Dom.
    Dom = {1}\/{2}\/{3},
    X in 1..3.