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!
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.