aggregateanswer-set-programmingclingogringo

ASP Clingo - getting the exact count of atoms


I'm looking forward to assign a specific count of persons to a specific shift. For example I got six persons and three different shifts. Now I have to assign exact two persons to every shift. I tried something like this but..
NOTE: this won't work, so please edit as fast as possible to misslead people, I even removed the "." after it so nobody is copying it:

person(a)
person(b)
person(c)
person(d)
person(e)
person(f)

shift("mor")
shift("aft")
shift("nig")

shiftCount(2).

{ assign(P,S) : shift(S)} = 1 :- person(P).

% DO NOT COPY THIS! SEE RIGHT ANSWER DOWN BELOW
:- #count{P : assign(P,"mor")} = K, shiftCount(K).
:- #count{P : assign(P,"aft")} = K, shiftCount(K).
:- #count{P : assign(P,"nig")} = K, shiftCount(K).


#show assign/2.

Is this possible to count the number of assigned shifts, so I can assign exactly as many people as a given number?

The output of the code above (when the "." are inserted) is:

clingo version 5.5.0
Reading from stdin
Solving...
Answer: 1
assign(a,"nig") assign(b,"aft") assign(c,"mor") assign(d,"mor")
assign(e,"mor") assign(f,"mor")
SATISFIABLE

Models       : 1+
Calls        : 1
Time         : 0.021s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time     : 0.000s

Here you can defently see, that the morning ("mor") shift is used more than two times, as difined in the shiftCount. What do I need to change to get the wanted result?


Solution

  • Replace your 3 lines constraints with

    {assign(P,S): person(P)} == K :- shift(S), shiftCount(K).
    

    or alternatively if you want to use the constraint writing:

    :- {assign(P,S): person(P)} != K, shift(S), shiftCount(K).
    

    First line states: For a given shiftCount K and for every shift S: the number of assignments over all people P for this shift S is K.
    The constraint reads: it can not be the case for a shiftCount K and a shift S that the number of assignments over all people P to the shift S is not K.

    Please do not alter your question / sample code dramatically since this may leads to the case that this answer won't work anymore.