Standard Modules¶
This only includes models that are usable by TLC. Reals and RealTime are not covered.
Naturals¶
Defines + - * ^ % < > <= >=
as well as
- Nat
The set
{0, 1, ...}
. Cannot be enumerated by TLC (used in a quantifier or a CHOOSE), but can be used for membership checking.a..b
The set
{a, a + 1, ..., b}
.a \div b
Floor division:
10 \div 3 = 3
.
Integers¶
Defines everything in Naturals
as well as
- Int
The set of all integers. Cannot be enumerated by TLC (used in a quantifier or a CHOOSE), but can be used for membership checking.
- -a
Negative numbers.
Sequences¶
Required for pluscal procedures. A sequence is like a list in any other language. You write it like <<a, b, c>>
, and the elements can be any other values (including other sequences).
Check the related section on sequences.
- Seq(set)
The set of all sequences where the values are all elements of
set
. TLC has special code to check if you’re testing membership, this is not memory/cpu intensive. Cannot be enumerated by TLC (used in a quantifier or a CHOOSE), but can be used for membership checking.<<a>> \in Seq({a, b}) <<a, b>> \in Seq({a, b}) <<a, b, b, a>> \in Seq({a, b}) \* in practice, the output is a set that contains all sequences made from 'a's and 'b's, \* so it also includes the sequence <<a, a, a, a, b, a, b>> for example. That's why it's nonenumerable.
- Len(seq)
Length of
seq
.Len(<<2, 4, 6>>) = 3
- Head(seq)
First element of
seq
.Head(<<1, 2, 3>>) = 1
- Tail(seq)
All but first element of
seq
.Tail(<<1, 2, 3>>) = <<2, 3>>
seq1 \o seq2
Concatenates two sequences.
<<1>> \o <<2 , 3>> = <<1, 2, 3>>
- Append(seq, e)
Append
e
at the end ofseq
. Equivalent toseq1 \o <<e>>
.Append(<<1, 2>>, 3) = <<1, 2, 3>>
- SubSeq(seq, m, n)
Used to select the subsequence
<<s[m], s[m+1], ... , s[n]>>
in seq. Indices are inclusive. [taken from docs]SubSeq(<<7, 8, 9>>, 1, 2) = <<7, 8>>
- SelectSeq(seq, Op(_))
Sequence filter using Op.
IsEven(x) == x % 2 SelectSeq(<<1, 2, 3>>, IsEven) = <<2>>
FiniteSets¶
- IsFiniteSet(set)
Tests if
set
is not an infinite set.IsFiniteSet({2, 5, 7}) = TRUE IsFiniteSet(Seq({1})) = FALSE IsFiniteSet(Nat) = FALSE
- Cardinality(set)
The number of elements in
set
.Cardinality({2, 5, 7}) = 3
Bags¶
Also known as multisets. Bags are functions items to “counts” of items. IE the struct [a |-> 1, b |-> 2]
is a bag. The values of a bag must be positive integers.
- IsABag(func)
Tests if
func
is a bag.IsABag([a |-> 3, b |-> 7]) = TRUE
- BagToSet(bag)
Equivalent to
DOMAIN bag
.BagToSet([a |-> 3, b |-> 7]) = {"a", "b"}
- SetToBag(set)
Equivalent to
[x \in set |-> 1]
.SetToBag({}) = <<>> SetToBag({"a","b"}) = [a |-> 1, b |-> 1] SetToBag({"a", "b", "a", "a"}) = [a |-> 1, b |-> 1]
- BagIn(e, bag)
Equivalent to
e \in DOMAIN bag
.BagIn("a", [a |-> 1, b |-> 1]) = TRUE BagIn("c", [a |-> 1, b |-> 1]) = FALSE
- EmptyBag
Equivalent to
<<>>
.EmptyBag = <<>>
bag1 (+) bag2
Bag addition. Creates a new bag where each key is the sum of the values of that key in each bag.
[a |-> 1, b |-> 3] (+) EmptyBag = [a |-> 1, b |-> 3] [a |-> 1, b |-> 3] (+) [a |-> 1] = [a |-> 2, b |-> 3] [a |-> 1, b |-> 3] (+) [c |-> 1] = [a |-> 1, b |-> 3, c |-> 1]
bag1 (-) bag2
Bad subtraction. If
bag2[e] >= bag1[e]
, thene
is dropped from the final bag’s keys.\* Nothing changes: [a |-> 1, b |-> 3] (-) EmptyBag = [a |-> 1, b |-> 3] \* a is removed from the bag: [a |-> 1, b |-> 3] (-) [a |-> 1] = [b |-> 3] \* a is decreased by the amount of the second bag: [a |-> 2, b |-> 3] (-) [a |-> 1] = [a |-> 1, b |-> 3] \* c is not in the domain of the bag on the left, hence nothing changes: [a |-> 1, b |-> 3] (-) [c |-> 1] = [a |-> 1, b |-> 3]
- BagUnion(set)
Equivalent to
bag1 (+) bag2 (+) ...
, whereset = {bag1, bag2, ...}
.BagUnion({}) = <<>> BagUnion({[a |-> 2]}) = [a |-> 2] BagUnion({[a |-> 2], [b |-> 3]}) = [a |-> 2, b |-> 3]
B1 \sqsubseteq B2
B1 sqsubseteq B2 iff, for all e in DOMAIN B1, bag B2 has at least as many copies of e as bag B1 does. [taken from docs]
[a |-> 2, b |-> 3] \sqsubseteq [b |-> 2] = FALSE [a |-> 2, b |-> 3] \sqsubseteq [a |-> 2, b |-> 2] = FALSE [a |-> 2, b |-> 3] \sqsubseteq [a |-> 2, b |-> 3] = TRUE \* it doesn't matter if B2 has "c |-> 1", because has enough copies of a and b. [a |-> 2, b |-> 3] \sqsubseteq [a |-> 2, b |-> 3, c |-> 1] = TRUE [a |-> 2, b |-> 3] \sqsubseteq [a |-> 5, b |-> 3, c |-> 1] = TRUE
- SubBag(bag)
The set of all subbags of
bag
.SubBag(EmptyBag) = {<<>>} SubBag([a |-> 2]) = {<<>>, [a |-> 1], [a |-> 2]}
- BagOfAll(Op(_), bag)
If
bag[e] = x
, thenout[Op(e)] = x
. egb == <<1, 3, 5>> >>> BagOfAll(LAMBDA x: x^2, b) (1 :> 1 @@ 4 :> 3 @@ 9 :> 5)
- BagCardinality(bag)
The sum of all values in
bag
.BagCardinality(EmptyBag) = 0 BagCardinality([a |-> 2]) = 2 BagCardinality([a |-> 5, b |-> 3, c |-> 1]) = 9
- CopiesIn(e, bag)
If
e
is inbag
, thenbag[e]
, otherwise 0.CopiesIn("a", EmptyBag) = 0 CopiesIn("a", [a |-> 5, b |-> 3]) = 5
TLC¶
Required for PlusCal assert. Many of the operators in TLC break core assumptions about TLA+, such as referential transparency. Use with caution!
a :> b
The function
[x \in {a} |-> b]
.func1 @@ func2
Function merge. If two functions share the same key, uses the value from
func1
(NOTfunc2
).- Permutations(set)
The set of all functions that act as permutations of
set
. eg>>> Permutations({"a", "b"}) {[b |-> "b", a |-> "a"], [b |-> "a", a |-> "b"]}
- SortSeq(seq, Op(_, _))
Sorts the sequence with comparator
Op
.- ToString(val)
String conversion.
- JavaTime
The current epoch time.
- Print(val, out)
Prints
ToString(val)
, and evaluates toout
as an expression.- PrintT(val)
Equivalent to
Print(val, TRUE)
.- Any
x \in Any
for any valuex
. Don’t use this as part of aSpec
, but it’s occasionally useful for modeling properties.- Assert(bool, errmsg)
If
bool
is false, then terminates model checking witherrmsg
. Otherwise, evaluates to TRUE.- RandomElement(set)
Randomly pulls an element from
set
. The value can be different on different runs!- TLCEval(v)
Evaluates the expression
v
and caches the result. Can be used to speed up recursive definitions.
- TLCGet(val)
val can be either an integer or a string. If an integer, retrieves the value from the corresponding TLCSet. If a string, retrieves statistics from the current model run. The following strings are valid:
“queue”
“generated”
“distinct”
“duration”: number of seconds elapsed since the beginning of model checking
“level”: the length of the current behavior
“diameter”: the length of the longest global behavior
“stats”: all of the global stats (everything excluding “level”), as a struct.
TLCGet("level")
can be used to bound an unbound model.- TLCSet(i, val)
Sets the value for
TLCGet(i)
.i
must be a positive integer. TLCSet can be called multiple times in the same step.Note
Each TLC worker thread carries a distinct “cache” for the values of
TLCGet(i)
. As such, it’s generally inadvisable to useTLCSet
to profile information that lasts beyond a single step.TLCSet statements evaluated during the initial state, however, will be propagated to all workers.
TLCExt¶
- AssertEq(a, b)
Equivalent to
a = b
, except that ifa # b
, it also prints the values ofa
andb
. This does not terminate model checking!- AssertError(str, exp)
True if
exp
doesn’t throw an error, or ifexp
throws an error that exactly matchesstr
. False otherwise.Note
AssertError catches the thrown error, meaning model checking will continue.
- Trace
Returns the “history” of the current behavior, as a sequence of structs.
- TLCModelValue(str)
Creates a new model value with name
str
. Can only be used in constant definitions, as part of an ordinary assignment.CONSTANT Threads <- { TLCModelValue(ToString(i)): i \in 1..3 }
Json¶
- ToJson(val)
Converts
val
to a JSON string. Sets and sequences are encoded as arrays, functions are encoded as objects with string keys.>>> ToJson(1..3) "[1,2,3]" >>> ToJson([x \in 0..2 |-> x^2]) "{\"0\":0,\"1\":1,\"2\":4}"
Multi-arity functions are encoded with keys that use the TLA+ tuple notation.
>>> ToJson([p, q \in BOOLEAN |-> p => q]) "{\"<<FALSE, FALSE>>\":true, \"<<TRUE, FALSE>>\":false, \* ...
- JsonSerialize(absoluteFilename, value)
Exports
value
as a JSON object to a file.- JsonDeserialize(absoluteFilename)
Imports a JSON object from a file.
Randomization¶
This module defines operators for choosing pseudo-random subsets of a set. If you use this, TLC will not check all possible states. For example, consider the spec
EXTENDS Integers, TLC, Randomization
VARIABLE x
Init ==
/\ x = 0
Next ==
\/ /\ x = 0
/\ x' \in {1, 2, 3}
\/ /\ PrintT(x)
/\ UNCHANGED x
\* Magic magic magic
Spec == Init /\ [][Next]_x
Running this will print the numbers {0, 1, 2, 3}. If we replace {1, 2, 3}
with RandomSubset(2, {1, 2, 3})
, then it will only print two of those three numbers, and which two may change from run to run. This makes Randomization
useful for optimization, but you need to be careful.
- RandomSubset(k, S)
Returns a random size-k subset of S.
RandomSubset(1, {"a"}) = {"a"} \* Running multiple times will yield different subsets RandomSubset(2, {"a", "b", "c"}) = {"b", "c"} RandomSubset(2, {"a", "b", "c"}) = {"a", "c"}
- RandomSetOfSubsets(k, n, S)
Selects k random subsets of S, where each random subset has on average n elements. Since this process may result in some duplicate subsets, the operator can potentially return fewer than k subsets. This can also potentially return the empty set.
RandomSetOfSubsets(1, 1, {"a"}) = {{"a"}} \* Each element has a 3-in-5 chance of appearing in each subset RandomSetOfSubsets(2, 3, {"a", "b", "c", "d", "e"}) = {{"a", "d", "c"}, {"a", "b", "e", "c"}} RandomSetOfSubsets(2, 3, {"a", "b", "c", "d", "e"}) = {{"a", "e"}, {"d", "e", "b", "c"}} \* Fewer than 4 results because it generated a duplicate RandomSetOfSubsets(4, 1, {"a", "b"}) = {{}, {"b"}, {"a", "b"}}
- TestRandomSetOfSubsets(k, n, S)
Calls
RandomSetOfSubsets(k, n, s)
five times and returns the number of unique sets returned each time.TestRandomSetOfSubsets(1, 1, {"a"}) = <<1, 1, 1, 1, 1>> \* Different executions will yield different results: TestRandomSetOfSubsets(3, 4, {"a", "b", "c", "d", "e"}) = <<3, 3, 2, 2, 2>>