combinatoricsanswer-set-programmingclingo

Generating Solution Candidates For Matching People in Clingo/ASP


I have a list of people and I want to pair them all then do some filtering based on preferences. When I generate my candidate solutions, how do I avoid creating candidate solutions that re-pair a people.

For example:

person(a;b;c;d) .
{match(X, Y): person(Y)}1 :- person(X) .

This generates candidate solutions that include match(a,b) match(c,b) ...

I would like ONLY candidate solutions that do not rematch anyone like: match(a,b) match(c,d) ...

My goal is to not have to filter rematches out via additional constraints. Also, not everyone needs to be matched. Thanks!


Solution

  • person(a;b;c;d).
    {match(A,B) : person(A), person(B), A < B}.
    :- person(A), 1 < {match(A,B); match(B,A)}.
    

    You exclude solutions that have more than 1 match for a single person.

    It is not possible to simply choose a correct set of atoms without additional constraints. As match(a,b) and match(b,c) can occur in different answer sets, both variables need to be created. Only a constraint can rule out that both do not occur in the same answer set.

    Also note that your generator rule

    {match(X, Y): person(Y)}1 :- person(X) .
    

    already is a shortcut writing for

    {match(X, Y): person(Y)} :- person(X).
    :- person(X), 2 {match(X, Y): person(Y)}.
    

    And therefore you are already using a constraint whenever your generator choice rule has non-trivial bounds.

    PS: Check the different versions using --stats=2 for constraint count and --text for a rough approximation of what kind of constraints are generated.