Page 293 of Software Abstractions says that these two are equivalent:
all x: X, y: Y | F
all x: X | all y: Y | F
but these two are not equivalent:
one x: X, y: Y | F
one x: X | one y: Y | F
Why are the latter two not equivalent?
I learn best with concrete examples, so let’s take a concrete example.
Last week I took a cruise to Alaska. At dinner I was seated with five other people. One of the couples (Jason and Denise) were celebrating their 25th (silver) wedding anniversary.
I created an Alloy model of the people at the dining table. The model specifies that there is one m: man, w: woman couple for which m's wife is w, w's husband is m, and m and w are celebrating a silver anniversary:
one m: Man, w: Woman |
m.wife = w and
w.husband = m and
m.anniversary = Silver and
w.anniversary = Silver
The instances that the Alloy Analyzer generated are what I expected.
Then I modified the expression to use nested expressions:
one m: Man |
one w: Woman |
m.wife = w and
w.husband = m and
m.anniversary = Silver and
w.anniversary = Silver
The Alloy Analyzer generated the same instances!
Next, I wrote an assertion, asserting that the two versions are equivalent:
Version1 iff Version2
The Alloy Analyzer returned: No counterexamples found!
Below is my model. Why are the two versions equivalent? Is there a small tweak that I could make to the model to show a difference between the nested version and the non-nested version?
Alloy Model of Roger's Dining Table on the Cruise to Alaska
abstract sig Man {
wife: lone Woman,
anniversary: lone Anniversary
}
one sig Roger extends Man {}
one sig Jason extends Man {}
abstract sig Woman {
husband: lone Man,
anniversary: lone Anniversary
}
one sig Faye extends Woman {}
one sig Nina extends Woman {}
one sig Claudia extends Woman {}
one sig Denise extends Woman {}
abstract sig Anniversary {}
one sig Silver extends Anniversary {}
pred v1_One_couple_celebrating_25th_wedding_anniversary {
one m: Man, w: Woman | m.wife = w and w.husband = m and
m.anniversary = Silver and w.anniversary = Silver }
pred v2_One_couple_celebrating_25th_wedding_anniversary {
one m: Man |
one w: Woman |
m.wife = w and w.husband = m and
m.anniversary = Silver and w.anniversary = Silver }
assert Both_versions_are_identical {
v1_One_couple_celebrating_25th_wedding_anniversary
iff
v2_One_couple_celebrating_25th_wedding_anniversary
}
check Both_versions_are_identical