Equivalences in Alloy
We say that two non-temporal Alloy expressions E1 and E2 of the same type are equivalent, written E1 ≡ E2, if they evaluate to the same value in every Alloy instance.
Below are some noteworthy equivalences in Alloy.
Set Operators
For all set/relations A, B, and C,
the following equivalences hold in Alloy
whenever their left- and right-hand sides are well typed:
- A & univ ≡ A
- A & none ≡ none
- A & A ≡ A
- A + A ≡ A
- A + univ ≡ univ
- A + none ≡ A
- A & B ≡ B & A
- A + B ≡ B + A
- A & (B & C) ≡ (A & B) & C
- A + (B + C) ≡ (A + B) + C
- A & (B + C) ≡ (A & B) + (A & C)
- A + (B & C) ≡ (A + B) & (A + C)
- A . (B . C) ≡ (A . B) . C
-
A . (B + C) ≡ (A . B) + (A . C)
-
(A + B) . C ≡ (A . C) + (B . C)
- ~~A ≡ A
- ~(A & B) ≡ ~A & ~B
- ~(A + B) ≡ ~A + ~B
- ~(A . B) ≡ ~B . ~A
- ~^A ≡ ^~A
- ~*A ≡ *~A
- ^A ≡ A
whenever is A is transitive
- *A ≡ A
whenever is A is reflexive and transitive
- ^^A ≡ ^A
- **A ≡ *A
Boolean Operators
Let ⊤ denote any formula that is alway true (e.g., none = none) and
let ⊥ denote any formula that is alway false (e.g., (none != none)).
For all set/relations A, B, C, and x where x is a singleton,
the following equivalences hold in Alloy
whenever their left- and right-hand sides are well typed:
- none in A ≡ ⊤
- some A and A in none ≡ ⊥
- A in A ≡ ⊤
-
A in B ≡
(A & B) = A
-
A in B ≡
(A + B) = B
-
A = B ≡
(A in B) and (B in A)
-
x in (A & B) ≡
(x in A) and (x in B)
-
x in (A + B) ≡
(x in A) or (x in B)
-
x in (A - B) ≡
(x in A) and (x !in B)
- no A ≡ A = none
- no A ≡ all x: A | ⊥
- some A ≡ A != none
- some A ≡ some x: A | ⊤
- lone A ≡ all x, y: A | x = y
- one A ≡ some x: A | x = A
- one A ≡
(some A) and all x, y: A | x = y
Boolean Connectives
For all formulas F, F1, F2, G, G1, and G2,
the following equivalences hold in Alloy:
- F and ⊤ ≡ F
- F or ⊤ ≡ ⊤
- F and ⊥ ≡ ⊥
- F or ⊥ ≡ F
- F and G ≡ G and F
- F or G ≡ G or F
- F and (G and H) ≡ (F and G) and H
- F or (G or H) ≡ (F or G) or H
- F and (G or H) ≡ (F and G) or (F and H)
- F or (G and H) ≡ (F or G) and (F or H)
- not not F ≡ F
- not (F and G) ≡ (not F) or (not G)
- not (F or G) ≡ (not F) and (not G)
- F implies G ≡ (not F) or G
- F implies ⊤ ≡ ⊤
- F implies ⊥ ≡ not F
- ⊤ implies G ≡ G
- ⊥ implies G ≡ ⊤
- not (F implies G) ≡ F and (not G)
-
(F1 and F2) implies G ≡
F1 implies (F2 implies G)
-
F implies (G1 and G2) ≡
(F implies G1) and (F implies G2)
-
(F1 or F2) implies G ≡
(F1 implies G) and
(F2 implies G)
-
F implies (G1 or G2) ≡
(F implies G1) or (F implies G2)
Quantifiers
For all formulas F and all sets A and B,
the following equivalences hold in Alloy:
- all x: A | ⊤ ≡ ⊤
- some x: A | ⊥ ≡ ⊥
- all x: none | F ≡ ⊤
- some x: none | F ≡ ⊥
-
all x: A | all y: B | F ≡
all y: B | all x: A | F
-
some x: A | some y: B | F ≡
some y: B | some x: A | F
- not all x: A | F ≡ some x: A | not F
- not some x: A | F ≡ all x: A | not F
-
all x: A | (F and G) ≡
(all x: A | F) and (all x: A | G)
-
some x: A | (F or G) ≡
(some x: A | F) or (some x: A | G)
-
no x: A | F ≡ all x: A | not F
- all x: A | F ≡ { x: A | F } = A
- some x: A | F ≡ some { x: A | F }
-
no x: A | F ≡ no { x: A | F }
-
one x: A | F ≡ one { x: A | F }
-
lone x: A | F ≡
(no x: A | F) or (one x: A | F)
Temporal operators
We say that two temporal Alloy formulas F and G are equivalent, written F ≡ G, if they are satisfied by exactly the same traces.
For all temporal formulas F and G,
the following equivalences hold in Alloy 6.
Note: Keep in mind that unary temporal operators bind more strongly than any binary operators.
(E.g., always F and G parses as (always F) and G, not as always (F and G).)
Future operators
- always F ≡ F and after always F
- eventually F ≡ F or after eventually F
- always always F ≡ always F
- eventually eventually F ≡ eventually F
- not always F ≡ eventually not F
- not eventually F ≡ always not F
- always (F and G) ≡
(always F) and (always G)
-
eventually (F or G) ≡
(eventually F) or (eventually G)
- not after F ≡ after not F
-
eventually F ≡
⊤ until F
-
F until G ≡
G or (F and after (F until G))
- after always before ⊤ ≡ ⊤
Past operators
-
historically F ≡
F and (not before ⊤ or before historically F)
-
once F ≡
F or before once F
- historically historically F ≡ historically F
- once once F ≡ once F
- not historically F ≡ once not F
- not once F ≡ historically not F
- historically (F and G) ≡
(historically F) and (historically G)
-
once (F or G) ≡
(once F) or (once G)
-
once F ≡
⊤ since F
-
F since G ≡
G or (F and before (F since G))