From last time:
sig City { roads: set City}
run {} for exactly 6 City
If we didn't have set before City then we'd only get one city because alloy defaults to one
if we don't specify a quantifier key word.
Now we want to make some contraints on the number of roads
pred multiplicityPractice {
some roads
one road
lone road
no road
}
run multiplicityPractice for exactly 6 City
But this is too many constraints! We cannot have some, one, lone, and no at the same time
Without no this works and gives us a self loop.
You'll be seeing these quantifiers a lot in the models you write.
Lets use only relational operators, multiplicities, and iden to eliminate self loops.
fact roadsGoSomewhere {
no ident & roads
}
pred someAll {
some c : City | all c2 : City - c | c2 in c.roads
}
run someAll for exactly 6 City
pred allSome {
all c : City | some c2 : City | c2 in c.roads
}
run allSome for exactly 6 City
These might look similar but are they the same? No!
someAll says: Give me an instance in which there exists a city that has a road to every other city.
allSome says: Give me an instance in which every city has a road to another city
Note: in someAll because of no self loops we need to take c out of the set of cities
Let's try and see if we can find some cycles among our cities.
This predicate will tell us if there is a cycle among a certain set of cities
pred isCycle[cities : set City] {
cities in cities.^roads
}
run isCycle for exactly 6 City
We have 2 conjectures: 1. that we might need disjoint 2. that our cycle pred might be broken
So let's test them out!
pred test {
some disj a, b, c, d : City | {
roads = a->b, + b->a + c->d + d->c
isCycle[a + b + c + d]
}
}
run test for exactly 6 City
Alloy gives us some counterexamples so we need to fix the cycle pred.
pred isCycleRound2[cities : set City] {
--cities in cities.^roads
let localRoads = roads + cities->cities
all c : cities | all c2 : cities - c | c2 in c.^localRoads
}
run isCycleRound2 for exactly 6 City