Alloy language preview
1. Address book model
The classic Alloy tutorial example: a sig hierarchy, a fact invariant, and a pred
horizon-dark
module addressBook
sig Name, Addr {}
sig Book {
addr: Name -> lone Addr
}
pred add [b, b': Book, n: Name, a: Addr] {
b'.addr = b.addr + n -> a
}
pred del [b, b': Book, n: Name] {
b'.addr = b.addr - n -> Addr
}
fact NoSelfLoop {
no n: Name | n in n.(addr.Book)
}
assert AddIdempotent {
all b, b', b'': Book, n: Name, a: Addr |
add[b, b', n, a] and add[b', b'', n, a] implies b'.addr = b''.addr
}
check AddIdempotent for 3 atom-one-dark
module addressBook
sig Name, Addr {}
sig Book {
addr: Name -> lone Addr
}
pred add [b, b': Book, n: Name, a: Addr] {
b'.addr = b.addr + n -> a
}
pred del [b, b': Book, n: Name] {
b'.addr = b.addr - n -> Addr
}
fact NoSelfLoop {
no n: Name | n in n.(addr.Book)
}
assert AddIdempotent {
all b, b', b'': Book, n: Name, a: Addr |
add[b, b', n, a] and add[b', b'', n, a] implies b'.addr = b''.addr
}
check AddIdempotent for 3 github-dark
module addressBook
sig Name, Addr {}
sig Book {
addr: Name -> lone Addr
}
pred add [b, b': Book, n: Name, a: Addr] {
b'.addr = b.addr + n -> a
}
pred del [b, b': Book, n: Name] {
b'.addr = b.addr - n -> Addr
}
fact NoSelfLoop {
no n: Name | n in n.(addr.Book)
}
assert AddIdempotent {
all b, b', b'': Book, n: Name, a: Addr |
add[b, b', n, a] and add[b', b'', n, a] implies b'.addr = b''.addr
}
check AddIdempotent for 3 dracula
module addressBook
sig Name, Addr {}
sig Book {
addr: Name -> lone Addr
}
pred add [b, b': Book, n: Name, a: Addr] {
b'.addr = b.addr + n -> a
}
pred del [b, b': Book, n: Name] {
b'.addr = b.addr - n -> Addr
}
fact NoSelfLoop {
no n: Name | n in n.(addr.Book)
}
assert AddIdempotent {
all b, b', b'': Book, n: Name, a: Addr |
add[b, b', n, a] and add[b', b'', n, a] implies b'.addr = b''.addr
}
check AddIdempotent for 3 nord
module addressBook
sig Name, Addr {}
sig Book {
addr: Name -> lone Addr
}
pred add [b, b': Book, n: Name, a: Addr] {
b'.addr = b.addr + n -> a
}
pred del [b, b': Book, n: Name] {
b'.addr = b.addr - n -> Addr
}
fact NoSelfLoop {
no n: Name | n in n.(addr.Book)
}
assert AddIdempotent {
all b, b', b'': Book, n: Name, a: Addr |
add[b, b', n, a] and add[b', b'', n, a] implies b'.addr = b''.addr
}
check AddIdempotent for 3 github
module addressBook
sig Name, Addr {}
sig Book {
addr: Name -> lone Addr
}
pred add [b, b': Book, n: Name, a: Addr] {
b'.addr = b.addr + n -> a
}
pred del [b, b': Book, n: Name] {
b'.addr = b.addr - n -> Addr
}
fact NoSelfLoop {
no n: Name | n in n.(addr.Book)
}
assert AddIdempotent {
all b, b', b'': Book, n: Name, a: Addr |
add[b, b', n, a] and add[b', b'', n, a] implies b'.addr = b''.addr
}
check AddIdempotent for 3 2. File system invariant
abstract sig with extends, and a fact enforcing tree shape
horizon-dark
abstract sig FSObject {}
sig File extends FSObject {}
sig Dir extends FSObject {
contents: set FSObject
}
one sig Root extends Dir {}
fact NoCycles {
all d: Dir | d not in d.^contents
}
fact OneParent {
all o: FSObject - Root | one d: Dir | o in d.contents
}
pred reachable [o: FSObject] {
o in Root.*contents
}
run reachable for 5 atom-one-dark
abstract sig FSObject {}
sig File extends FSObject {}
sig Dir extends FSObject {
contents: set FSObject
}
one sig Root extends Dir {}
fact NoCycles {
all d: Dir | d not in d.^contents
}
fact OneParent {
all o: FSObject - Root | one d: Dir | o in d.contents
}
pred reachable [o: FSObject] {
o in Root.*contents
}
run reachable for 5 github-dark
abstract sig FSObject {}
sig File extends FSObject {}
sig Dir extends FSObject {
contents: set FSObject
}
one sig Root extends Dir {}
fact NoCycles {
all d: Dir | d not in d.^contents
}
fact OneParent {
all o: FSObject - Root | one d: Dir | o in d.contents
}
pred reachable [o: FSObject] {
o in Root.*contents
}
run reachable for 5 dracula
abstract sig FSObject {}
sig File extends FSObject {}
sig Dir extends FSObject {
contents: set FSObject
}
one sig Root extends Dir {}
fact NoCycles {
all d: Dir | d not in d.^contents
}
fact OneParent {
all o: FSObject - Root | one d: Dir | o in d.contents
}
pred reachable [o: FSObject] {
o in Root.*contents
}
run reachable for 5 nord
abstract sig FSObject {}
sig File extends FSObject {}
sig Dir extends FSObject {
contents: set FSObject
}
one sig Root extends Dir {}
fact NoCycles {
all d: Dir | d not in d.^contents
}
fact OneParent {
all o: FSObject - Root | one d: Dir | o in d.contents
}
pred reachable [o: FSObject] {
o in Root.*contents
}
run reachable for 5 github
abstract sig FSObject {}
sig File extends FSObject {}
sig Dir extends FSObject {
contents: set FSObject
}
one sig Root extends Dir {}
fact NoCycles {
all d: Dir | d not in d.^contents
}
fact OneParent {
all o: FSObject - Root | one d: Dir | o in d.contents
}
pred reachable [o: FSObject] {
o in Root.*contents
}
run reachable for 5 3. Ring leader election
disj/lone quantifiers and a check with a scope
horizon-dark
sig Process {
succ: lone Process,
id: one Int
}
fact Ring {
all p: Process | Process in p.^succ
}
pred distinctIds {
all disj p1, p2: Process | p1.id != p2.id
}
pred isLeader [p: Process] {
all q: Process - p | p.id.gt[q.id]
}
assert OneLeader {
distinctIds implies (lone p: Process | isLeader[p])
}
check OneLeader for 6 Process atom-one-dark
sig Process {
succ: lone Process,
id: one Int
}
fact Ring {
all p: Process | Process in p.^succ
}
pred distinctIds {
all disj p1, p2: Process | p1.id != p2.id
}
pred isLeader [p: Process] {
all q: Process - p | p.id.gt[q.id]
}
assert OneLeader {
distinctIds implies (lone p: Process | isLeader[p])
}
check OneLeader for 6 Process github-dark
sig Process {
succ: lone Process,
id: one Int
}
fact Ring {
all p: Process | Process in p.^succ
}
pred distinctIds {
all disj p1, p2: Process | p1.id != p2.id
}
pred isLeader [p: Process] {
all q: Process - p | p.id.gt[q.id]
}
assert OneLeader {
distinctIds implies (lone p: Process | isLeader[p])
}
check OneLeader for 6 Process dracula
sig Process {
succ: lone Process,
id: one Int
}
fact Ring {
all p: Process | Process in p.^succ
}
pred distinctIds {
all disj p1, p2: Process | p1.id != p2.id
}
pred isLeader [p: Process] {
all q: Process - p | p.id.gt[q.id]
}
assert OneLeader {
distinctIds implies (lone p: Process | isLeader[p])
}
check OneLeader for 6 Process nord
sig Process {
succ: lone Process,
id: one Int
}
fact Ring {
all p: Process | Process in p.^succ
}
pred distinctIds {
all disj p1, p2: Process | p1.id != p2.id
}
pred isLeader [p: Process] {
all q: Process - p | p.id.gt[q.id]
}
assert OneLeader {
distinctIds implies (lone p: Process | isLeader[p])
}
check OneLeader for 6 Process github
sig Process {
succ: lone Process,
id: one Int
}
fact Ring {
all p: Process | Process in p.^succ
}
pred distinctIds {
all disj p1, p2: Process | p1.id != p2.id
}
pred isLeader [p: Process] {
all q: Process - p | p.id.gt[q.id]
}
assert OneLeader {
distinctIds implies (lone p: Process | isLeader[p])
}
check OneLeader for 6 Process