Skolemization turns things from syntactic criterion of true and false and turned it into a first-class citizen of the instance.
Skolemization is about looking for (hidden) sums or quantifiers, turning them from the world of syntax to real-life parts of the alloy instance.
This allows us to not just look up True/False values in the Evaluator, but to see the physical embodiment of a function in our alloy instance.
We want to establish a Skolem function:
one sig Skolem {witness: City -> one City }
Existential quanitifier that we turn into a function embodied in the instance.
pred allSome2 {
all c: City -> some Skolem.witness[c] in roads
}
Q: What do the square brackets mean?
Tim: They are exactly the opposite of the .
relational join operator. (Skolem.witness)[c] = c.(Skolem.witness)
Q: Does Skolemization give us anything more than a clearer visualisation of an instance?
Tim: Yes, we'll get to it in a second!
Can also change the skolem depth, 1->n.
The standard is for the Skolem depth to be 0.
At each depth, Alloy skolemises a new depth of quantifiers. For depth 0, only universal are skolemised. For depth 1, universal and the first layer of existential predicates are skolemised, etc.
In our instance, this created an $allSome_c2
as a relation for the cities.
Logician speak: universal quantifiers are all, existential quantifiers are some. (No is just a type of existential quantifier.)
Look at what happens when we quantify over a set. Example:
pred someSet {
some cities: set City | some cities.roads
}
run someSet for exactly 5 City
This is saying there exists some set of City, such that that set of City has a road. Trivial example using set quantification for class.
The difference is: this needs to be a relation of columns rather than just finding one City.
What happens when we try to run the same predicate with a universal quantifier?
pred allSet {
all cities: set City | some cities.roads
}
We get an error message! A type error has ocured: Analysis cannot be performed since it requires higher-order quantification that could not be skolemized.
Because this involves exponential resolution, the Alloy solver won't attempt to solve this. For now, stay away from universal higher-order quantification.
Q: Why doesn't Alloy just have a limit and then an overflow? Why isn't it just capped?
Tim: I am not really sure, but we can hack Alloy to see!
New attempt:
pred test {
some cities: set City | some c2: City |
cities->c2 in roads
}
run test for exactly 5 City
We are looking at some cities.roads
versus the some quantifier some cs: City
. Changing Skolem depth to 0. This indeed skolemises $test_cities
and $test_c2
.
The some
in some cities.roads
is not actually a quantifier, it just looks at the size of the set. Therefore, it will not be Skolemised.
Q: How does an Assertion works?
Tim: An Assertion in Alloy negates the statement and then tries to find a counterexample.
Be careful! Even if you have a some
in your spec, you can still end up getting the higher-order quantification error. This probably means there is some equivalency to an all
quantifier somewhere in your spec.
Moving on!
We now have a spec that defines many of the things we find at university: Students, Courses, Faculty, etc.
Let's define a sig CourseState {}
.
What is a property of 195Y/A Course?
id: CourseID
enrolled: set Student
where: Room
instructor: Faculty
when: TimeSlot
tas: set Student
waitlist: set Students
BUT, what's missing from the set
datatype which is insufficient for a waitlist? waitlist: seq Student