I'm trying to create 5 marriages, given 5 women and 5 man and their preferences to each other.
homem(miguel).
homem(joao).
homem(pedro).
homem(marco).
homem(carlos).
mulher(maria).
mulher(paula).
mulher(carla).
mulher(cristina).
mulher(ana).
all the marriages are stable (it is unstable if 2 person outside the marriage prefer each other more than their spouses), and I have their preferences to each other by ranks:
pref(miguel,paula,5).
pref(miguel,ana,4).
pref(miguel,maria,3).
pref(miguel,carla,2).
pref(miguel,cristina,1).
pref(maria,carlos,5).
pref(maria,miguel,4).
pref(maria,marco,3).
pref(maria,joao,2).
pref(maria,pedro,1).
pref(joao,maria,5).
pref(joao,paula,4).
pref(joao,carla,3).
pref(joao,cristina,2).
pref(joao,ana,1).
pref(paula,marco,5).
pref(paula,carlos,4).
pref(paula,joao,3).
pref(paula,miguel,2).
pref(paula,pedro,1).
pref(pedro,paula,5).
pref(pedro,carla,4).
pref(pedro,ana,3).
pref(pedro,cristina,2).
pref(pedro,maria,1).
pref(carla,miguel,5).
pref(carla,marco,4).
pref(carla,joao,3).
pref(carla,pedro,2).
pref(carla,carlos,1).
pref(marco,maria,5).
pref(marco,carla,4).
pref(marco,paula,3).
pref(marco,cristina,2).
pref(marco,ana,1).
pref(cristina,pedro,5).
pref(cristina,joao,4).
pref(cristina,marco,3).
pref(cristina,miguel,2).
pref(cristina,carlos,1).
pref(carlos,ana,5).
pref(carlos,carla,4).
pref(carlos,paula,3).
pref(carlos,maria,2).
pref(carlos,cristina,1).
pref(ana,marco,5).
pref(ana,joao,4).
pref(ana,pedro,3).
pref(ana,carlos,2).
pref(ana,miguel,1).
casamento(1..5).
% every person belongs to one group only.
1{in(H,M): casamento(C)}1 :- homem(H), mulher(M).
:- homem(H1), mulher(M1), homem(H2), mulher(M2),
pref(H1,M2,P1),pref(H1,M1,P2), P1>P2,
pref(M2,H1,P3), pref(M2,H2,P4); P3>P4.
but this does not work and I don't know why.
Problem 1
The rule
1{in(H,M): casamento(C)}1 :- homem(H), mulher(M).
doesn't mean that "every person belongs to one group only", but that "every pair of man and woman belongs to exactly one marriage. This is equivalent to say that every man is married with every woman.
Instead, you should express the contrary: every marriage should "generate" exactly one pair of people:
1{in(H,M,C): homem(H), mulher(M)}1 :- casamento(C) .
But this doesn't prevent a men (or woman) to belong to two different marriages. So you shoul also add:
:- in(H,M1,C1), in(H,M2,C2), C1!=C2 .
:- in(H1,M,C1), in(H2,M,C2), C1!=C2 .
Problem 2
Moreover, in your constraint you're considering every pair of people (not every pair of married people!). So you should replace homem(H1), mulher(M1), homem(H2), mulher(M2) with in(H1,M1,C1), in(H2,M2,C2).
Fixed code
casamento(1..5) .
1{in(H,M,C): homem(H), mulher(M)}1 :- casamento(C) .
:- in(H,M1,C1), in(H,M2,C2), C1!=C2 .
:- in(H1,M,C1), in(H2,M,C2), C1!=C2 .
:- in(H1,M1,C1), in(H2,M2,C2),
pref(H1,M2,P1), pref(H1,M1,P2), P1>P2,
pref(M2,H1,P3), pref(M2,H2,P4), P3>P4 .
This program (plus the EDB in your example) generates the following marriages:
in(miguel,carla,2) in(marco,paula,3) in(joao,cristina,1) in(carlos,maria,4) in(pedro,ana,5)
Optional
If you don't want to hardcode the 5 and make it work for any number of people in input, you can dynamically count the number of women (or men, assuming that it's the same).
So you can replace casamento(1..N). with:
casamento(1..N) :- N = #count{ X : mulher(X) } .
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?
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.
I am trying to write a story generator in Clingo.
I am trying to say "new characters can be born if existing characters give birth to them." I define new characters as entity(<int\>), which is the best way I could think of to representing entities. I cannot hardcode this as varying number of entities can be created in a story.
My code is :
% Create instances of time, only 3 for testing
time(0..2).
% Arrow of time flows forward
next_t(T, T+1) :- time(T), time(T+1).
% Entity 1 exists at time 0.
entity(1, 0).
% If an entity ever existed, that ID is taken and cannot be assigned to
% other entities
entity_id(ID) :- entity(ID, _).
% If an entity exists, he can give birth to a new entity
% The ID of the new entity will be 1 more than ID of all current entities.
birth(X, Y, T) :- entity(Y, T), X = #max{X1+1:entity_id(X1)}, time(T).
% At each time instant, only 1 entity can be born, as only 1 event can happen per time instant.
% This also should prevent infinite entities to be created.
:- birth(X1, _, T), birth(Y1, _, T), X1!=Y1.
% In case of a birth, create a new entiti the next time instant.
entity(X, T1) :- birth(X, _, T), next(T, T1).
#show entity_id/1.
#show entity/2.
#show birth/3 .
However, output is :
entity_id(1) entity(1,0) birth(2,1,0)
entity(2, 1) is never created, nor are entity(3, 2) or entity(4, 3).
What am I doing wrong? Is there a better way to do this?
You seem to be thinking that ASP statements happen in order from first to last or something like that.
But in fact they're just rules about a collection of atoms. The rules always hold. In particular, the rule:
entity_id(ID) :- entity(ID, _).
says nothing about duplicates. It just says that for every entity which has an ID ID, ID is an entity_id.
If you want to encode the rule that each ID is used once, you should write it as:
:- {entity(ID,_)} > 1; entity_id(ID).
Also you try to construct "ID's" which are "one more than all current entities", but there's no such thing as "current" entities. All we have to guide us are the time-steps.
Let's try writing this in a way that keeps our timesteps explicit throughout.
% Create instances of time, only 3 for testing
time(0..2).
% Entity eve exists at time 0.
entity(1, 0).
nextID(2, 0).
% If an entity existed at the previous time-step, they continue to exist
% at the next time-step (as I understand, no entity dies).
entity(ID, T) :- entity(ID, T-1); time(T).
% Any entity who was alive on the previous time-step can give birth to
% a child at time T. This child's ID is the current `nextID`
% Note this is a _choice_ rule. The entity _can_ give birth, they don't
% have to. Also we only allow at most one of these births to happen at
% each time-step.
{birth(ChildID, ParentID, T) : entity(ParentID,T-1)} <= 1 :- nextID(ChildID,T).
% Once born, an ID becomes an entity.
entity(ID,T) :- birth(ID,_,T).
% If an entity was born at the previous time-step, the nextID increases by one
% for this time-step.
nextID(ID+1,T) :- nextID(ID,T-1); time(T); entity(ID,T-1).
% Otherwise it stays the same.
nextID(ID,T) :- nextID(ID,T-1); time(T); not entity(ID,T-1).
#show birth/3.
Running this I find there are 5 models.
$ clingo entities.asp 0
clingo version 5.3.1
Reading from entities.asp
Solving...
Answer: 1
% ^ Nobody is ever born
Answer: 2
birth(2,1,2)
% ^ Nobody born at time 1. 1 births a child at time 2
Answer: 3
birth(2,1,1) birth(3,2,2)
% ^ 1 births a child at time 1 and that child gives birth at time 2.
Answer: 4
birth(2,1,1)
% ^ 1 births a child at time 1. Nobody is born at time 2.
Answer: 5
birth(2,1,1) birth(3,1,2)
% ^ 1 births two children; one at time 1 and another at time 2.
SATISFIABLE
Models : 5
Calls : 1
Time : 0.011s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time : 0.004s