Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Sets and Sequences

Sets

Finite, unordered collections with no duplicates.

Literals and comprehensions

{1, 2, 3}                                    // literal
{}                                            // empty set
{p in 0..N if state[p] == 1}                  // comprehension (filter)

Set operations

OperationSyntaxResult
Membershipx in SBool
Non-membershipx not in SBool
UnionS1 union S2Set[T]
IntersectionS1 intersect S2Set[T]
DifferenceS1 diff S2Set[T]
SubsetS1 subset_of S2Bool
Sizelen(S)Int
Powersetpowerset(S)Set[Set[T]]
Flattenunion_all(S)flattens Set[Set[T]] to Set[T]

Counting pattern

Use comprehensions with len to count:

// Count processes in a given state
len({p in 0..N if role[p] == 2})

// Quorum check
len({v in 0..N if voted[v]}) * 2 > N + 1

Sequences

Ordered collections (0-indexed).

Literals

[]                     // empty
[1, 2, 3]             // literal

Sequence operations

OperationSyntaxResult
Indexs[i]element at position i
Lengthlen(s)Int
Headhead(s)first element
Tailtail(s)all but first
Concats1 ++ s2Seq[T]
Slices[lo..hi]subsequence from lo to hi
Appends ++ [x]append element x
Prepend[x] ++ sprepend element x

Message passing with sequences

A common pattern is to encode messages as sequences with typed fields:

var msgs: Set[Seq[Int]]

// Message: [type, src, dst, payload]
action Send(src: 0..N, dst: 0..N) {
    msgs = msgs union {[1, src, dst, currentTerm[src]]}
}

action Receive(src: 0..N, dst: 0..N, term: Int) {
    require [1, src, dst, term] in msgs
    // process...
}

Log operations

Sequences are used for logs in consensus protocols:

var log: Dict[Int, Seq[Int]]

// Append entry
log = log | {i: log[i] ++ [value]}

// Last element
let lastTerm = if len(log[i]) == 0 then 0 else log[i][len(log[i]) - 1]

// Truncate (keep first k entries)
log = log | {i: log[i][0..k]}