Reputation: 1
I am new to Alloy and I am trying to make this predicate to work but I don't know where is the problem. The users can join the party or create during the time for candidacy, the governor is the one who announces the elections and candidacy period, the users can vote for one party and put three preferences on candidates from that party. I do not know why it cannot find an instance. Can you help me?
module Politics
abstract sig Document{ }
abstract sig Photo{ }
sig Party{
id:one Int,
name:one String,
program:one Document,
symbol :one Photo,
CreateDate: one Int
}{CreateDate>Election.startCandidacy
CreateDate<Election.EndCandidacy}
sig User{
id: one Int,
name: one String,
surname: one String,
email: one String,
password: one String,
dateBirth: one Int,
vote: lone Vote
}
sig Governor extends User{
election:one Election,
}{vote != none}
abstract sig Candidate extends User{
cv: one Document,
motLetter: one Document,
party: one Party,
dateCand : one Int
}{cv !=motLetter
vote != none
dateCand > Election.startCandidacy
dateCand < Election.EndCandidacy}
one sig Election{
startCandidacy:one Int,
EndCandidacy:one Int,
dateElection: one Int
}{startCandidacy < EndCandidacy
dateElection>EndCandidacy}
sig Vote{
dateVote: one Int,
preference1: one Candidate,
preference2: lone Candidate,
preference3: lone Candidate
}{preference1 != preference2
preference1 != preference3
preference2 != preference3
dateVote = Election.dateElection}
// Facts
// Every user has a unique ID and username
fact noTwoUsersWithSameID{
no disj u1, u2 : User | u1.id = u2.id || u1.email = u2.email
}
// Every party is unique, with unique name, program and symbol
fact noTwoSameParties{
no disj p1, p2 : Party | p1.name = p2.name || p1.program = p2.program || p1.symbol = p2.symbol
}
// Every candidate has a unique cv and motivation letter
fact noTwoSameCandidates{
no disj c1, c2 : Candidate | c1.cv = c2.cv || c1.motLetter = c2.motLetter
}
// All preferences in the vote are on the same party
fact AllPreferencesSameParty{
all v: Vote | v.preference1.party = v.preference2.party and v.preference1.party = v.preference3.party
}
fact noSameVotes{
no disj u1, u2:User | u1.vote = u2.vote
all v:Vote | one u:User | u.vote = v
}
assert NoSameUsers{
no disj u1, u2 : User | u1.id = u2.id || u1.email = u2.email
}
check NoSameUsers for 4
pred show()
{
#Election > 1
//#Party > 3
#Candidate > 8
#User > 10
}
run show for 12
Upvotes: 0
Views: 720
Reputation: 25034
You're on the right track.
Your example shows that you've already tried one simple approach to figuring out why no instances are being found: relaxing the constraints to see which constraint is causing the model not to be instantiated. Specifically, you've commented out part of the show
predicate.
If you do a bit more of that, you'll find that if you comment out all of the constraints in show
, so it becomes vacuous, Alloy will find instances. If you bring the constraints back in one by one, you'll find that show
is satisfiable when, and only when, the constraint #Election > 1
is commented out.
This should direct your attention to the declaration for Election, which takes the form one sig Election { ... }
. Do you see now why you are finding no instances of show
? No instance can simultaneously satisfy the constraint that there be more than one election and the constraint that there be exactly one election.
In general, I think you'll be happier with Alloy if you learn to rely less on integers for uniqueness and for sequencing events. Alloy atoms have what is sometimes called object identity, so they don't need to have unique identifiers for bookkeeping purposes.
Upvotes: 1