{"id":20397301,"url":"https://github.com/tlaplus/pluscalcheatsheet","last_synced_at":"2026-02-05T21:31:51.366Z","repository":{"id":152785766,"uuid":"381479679","full_name":"tlaplus/PlusCalCheatSheet","owner":"tlaplus","description":"PlusCal Cheat Sheet by Stephan Merz","archived":false,"fork":false,"pushed_at":"2024-09-27T23:35:58.000Z","size":224,"stargazers_count":20,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-12T01:50:28.616Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://d3s.mff.cuni.cz/f/teaching/nswi101/pluscal.pdf","language":"TeX","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tlaplus.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-29T19:46:36.000Z","updated_at":"2024-09-27T23:36:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"8ecfe529-003c-4ae5-b7b0-87c5bd9a3198","html_url":"https://github.com/tlaplus/PlusCalCheatSheet","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tlaplus/PlusCalCheatSheet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlaplus%2FPlusCalCheatSheet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlaplus%2FPlusCalCheatSheet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlaplus%2FPlusCalCheatSheet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlaplus%2FPlusCalCheatSheet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tlaplus","download_url":"https://codeload.github.com/tlaplus/PlusCalCheatSheet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlaplus%2FPlusCalCheatSheet/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267144749,"owners_count":24042641,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-26T02:00:08.937Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T04:13:12.161Z","updated_at":"2026-02-05T21:31:51.308Z","avatar_url":"https://github.com/tlaplus.png","language":"TeX","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\nabstract: |\n    This document is intended to summarize the main constructs that a user\n    of PlusCal and TLA^+^ who is using the Toolbox and TLC is likely to\n    encounter. It does not replace the available introductory material about\n    TLA^+^ and is also not meant as a reference manual. Feedback to the\n    author is welcome.\nauthor:\n- |\n    Stephan Merz\\\n    [stephan.merz\\@loria.fr](stephan.merz@loria.fr)\ntitle: 'PlusCal / : An Annotated Cheat Sheet'\n---\n\nPlusCal\n=======\n\nPlusCal is an algorithmic language that has the \"look and feel\" of\nimperative pseudo-code for describing concurrent algorithms. It has a\nformal semantics, through translation to TLA^+^, and algorithms can be\nverified using the TLA^+^ tools. We describe here the \"C syntax\" of\nPlusCal, but there is also a \"P syntax\" closer to the Pascal programming\nlanguage.\n\nA PlusCal algorithm appears inside a comment within a TLA^+^ module. Its\ntop-level syntax is as follows.\n\n    --algorithm name {\n      (* declaration of global variables *)\n      (* operator definitions *)\n      (* macro definitions *)\n      (* procedures *)\n      (* algorithm body or process declarations *)\n    }\n\nVariable declarations, operator and macro definitions, as well as\nprocedures are optional. There must either be an algorithm body (for a\nsequential algorithm) or process declarations (for a concurrent\nalgorithm).\n\nThe PlusCal translator embeds the TLA^+^ specification corresponding to\nthe PlusCal algorithm in the module within which the algorithm appears,\nimmediately following the algorithm. The translation is delimited by the\nlines\n\n    \\* BEGIN TRANSLATION\n    ...\n    \\* END TRANSLATION\n\nUsers should not touch this area, as it will be overwritten whenever the\nPlusCal translator is invoked. However, TLA^+^ definitions may appear\neither before the PlusCal algorithm or after the generated TLA^+^\nspecification. In particular, operators defined before the PlusCal\nalgorithm may be used in the algorithm. Correctness properties are\ndefined below the generated specification because they refer to the\nvariables declared by the translator.\n\n#### Variable declarations.\n\nVariables are declared as follows, they may (but need not) be\ninitialized:\n\n`variables x, y=0, z \\in {1,2,3};`\n\nNote that there may be at most one \"variables\" clause, but that it may\ndeclare any number of variables. This example declares three variables\n$x$, $y$, and $z$. The variable $x$ is not initialized, $y$ is\ninitialized to $0$, and $z$ may take either $1$, $2$ or $3$ as initial\nvalues. During model checking, TLC will assign $x$ a default value that\nis different from all ordinary values and will explore all three initial\nvalues for $z$.\n\n#### Operator definitions.\n\nAs in TLA^+^(see below), operators represent utility functions for\ndescribing the algorithm. The syntax is the same as for TLA^+^\ndefinitions, explained below. For example,\n\n    define {\n      Cons(x,s) == \u003c\u003c x \u003e\u003e \\o s\n      Front(s)  == [i \\in 1 .. Len(s)-1 |-\u003e s[i]]\n    }\n\ndeclares an operator $\\mathit{Cons}$ that prepends an element $x$ to a\nsequence $s$ and an operator $\\mathit{Front}$ that returns the\nsubsequence of a non-empty sequence without the last element. Again,\nthere can be a single \"define\" clause, but it may contain any number of\noperator definitions, without any separator symbol.\n\n#### Macros.\n\nA macro represents several PlusCal statements that can be inserted into\nan algorithm, and it may have parameters. In contrast to a defined\noperator, a macro need not be purely functional but may have side\neffects. In contrast to a procedure, it cannot be recursive and may not\ncontain labels or complex statements such as loops or procedure calls or\nreturn statements. Here are two examples:\n\n    macro send(to, msg) {\n      network[to] := Append(@, msg)\n    }\n    macro rcv(p, var) {\n      await Len(network[p]) \u003e 0;\n      var := Head(network[p]);\n      network[p] := Tail(@)\n    }\n\nThese macros represent send and receive operations in a network\nrepresented by FIFO queues indexed by processes. The first macro appends\na message to the queue of the destination process. The second macro\nblocks until the queue of process $p$ contains at least a message, then\nassigns the first message in the queue to variable $\\mathit{var}$ and\nremoves it from that queue. When using a macro, simply insert an\ninvocation as a statement in the code, such as `send(p, x+1)` for\nsending the value $x+1$ to process $p$.\n\n#### Procedures.\n\nA procedure declaration is similar to that of a macro, but it may also\ncontain the declaration of local variables.[^1] The procedure body may\ncontain arbitrary statements, including procedure calls (even recursive\ncalls).\n\n    procedure p(x,y)\n        variable z=x+1  \\* procedure-local variable\n    {\n        call q(z,y);\n    l:  y := y+1;\n        return\n    }\n\nProcedure parameters are treated as variables and may be assigned to.\nAny control flow in a procedure should reach a return statement, any\nresult computed by the procedure should be stored in a\nvariable---possibly a parameter. Procedure calls are preceded by the\nkeyword call and must be followed by a label.\n\nSince the PlusCal translator introduces a stack for handling procedures,\na PlusCal algorithm using procedures must appear in a module\n[[extend]{.smallcaps}]{.nodecor}ing the standard module `Sequences`.\n\n#### Processes.\n\nA PlusCal algorithm may declare one or more process templates, each of\nwhich can have several instances. A process template looks as follows:\n\n    process (name [= | \\in] e)\n       variables ...   \\* process-local variables\n    {\n       (* process body *)\n    }\n\nThe form \"$name = e$\" will give rise to one instance of the process\nwhose process identity is (the value of expression) $e$, whereas\n\"$name \\in e$\" will create one process instance per element of the set\n$e$. When creating several process instances from different templates,\nit is important to ensure that all process identities are comparable and\ndifferent: for example, use only integers, only strings or only model\nvalues. Within the process body, the process identity is referred to as\n`self` (and not as `name` as the syntax might suggest). Processes\nconceptually execute (asynchronously) in parallel, from the start of\nexecution of the algorithms: PlusCal does not support dynamically\nspawning processes during execution.\n\n#### PlusCal statements.\n\nThe statements of PlusCal are those expected of a simple imperative\nlanguage, with the addition of primitives for synchronization and for\nnon-deterministic choice that are useful for specifications.\n\nAssignments are written `x := e`, but PlusCal also supports assignments\nto components of an array `x[i,j] := e` whose translation involves\n[[except]{.smallcaps}]{.nodecor} forms in TLA^+^. PlusCal also has a\nstatement `print e` for printing the value of an expression.[^2]\nHowever, due to the breadth-first state enumeration strategy used by\ndefault in TLC, it may not always be obvious to understand the\nrelationship between outputs to the console and actual execution flow.\n\nThe conditional statement has the usual form\n\n       if (exp) ... else ...\n\nwhere the \"else\" branch is optional; compound statements are enclosed in\nbraces. Similarly, while loops are written\n\n       while (exp) ...\n\nOther statements for transferring the flow of control are procedure call\nand return (see above), as well as `goto l` for jumping to label\n$l$---see below for a more detailed explanation of labels in PlusCal.\n\nAssertions can be embedded in PlusCal in the form `assert e`. This\nstatement has no effect if the predicate $e$ is true and otherwise\naborts (producing a counter-example trace in TLC). There is also `skip`,\nwhich does nothing and is equivalent to `assert TRUE`.\n\nThe statement `await e` (which can alternatively be written `when e`)\nblocks execution until the condition is true. This is useful for\nsynchronizing parallel processes, for example for blocking message\nreception until a message has actually been received.\n\nFinally, PlusCal offers two statements for modeling non-determinism. The\nfirst form,\n\n      either \\* first choice\n      or     \\* second choice\n      or     \\* ...\n\nis useful for expressing the choice between a fixed number of\nalternatives. A useful idiom for restricting this choice is to add\n`await` statements to branches: only those choices whose condition\nevaluate to [[true]{.smallcaps}]{.nodecor} can indeed be executed. (This\nis PlusCal's version of Dijkstra's guarded commands.)\n\nSecond, the form\n\n       with (x \\in S) ...\n\nallows for choices based on the elements of set $S$: the variable $x$\nacts as a local variable whose scope is restricted to the body of the\n`with` statement. For example, in a model where communication is not\nnecessarily FIFO, $S$ could be the set of messages that a process has\nreceived, and a `with` statement could be used to handle any one of\nthese messages.\n\n#### Semicolons.\n\nUnlike in C and similar languages, PlusCal uses semicolons to separate\n(and not end) statements. In particular, this means that no semicolon is\nrequired before the closing brace of a compound statement (although it\nis not considered as a syntax error). However, a semicolon is required\n*after* the closing brace if it is followed by another statement.\n\n#### Labels.\n\nPlusCal statements can be labeled, and the primary purpose of labels is\nto indicate the \"grain of atomicity\" in the execution of parallel\nprocesses. The idea is that a group of statements that appears between\ntwo labels is executed without interruption by any other process.\nHowever, the PlusCal translator imposes certain labeling rules. The most\nimportant ones are:\n\n-   The first statement in the body of a procedure, a process or of the\n    algorithm body must be labeled.\n\n-   A `while` statement must be labeled.\n\n-   Any statement following a `call`, a `return` or an `if` or\n    `either` statement that contains a labeled statement must be\n    labeled.\n\n-   A macro body and the body of a `with` statement may not contain\n    labels.\n\n-   Any two assignments to the same variable (including to two\n    components of the same array) must be separated by a label.\n\nThe full set of labeling rules is given in the PlusCal manual. The\ntranslator prints information about missing labels, it may also be run\nwith the `-label` option to automatically add missing labels.\n\n#### Specifying Fairness.\n\nFairness conditions require that statements that are \"often enough\"\nenabled must eventually be executed; they are necessary in order to\nensure that an algorithm satisfies any liveness property. In PlusCal,\nfairness conditions can be attached to the algorithm, process templates\nor labels. By writing `fair algorithm`, one requires that some statement\n(for some process) must eventually be executed if some statement is\nenabled. This is a weak condition: in particular, some process may never\nexecute although it is always enabled, if other processes are also\nalways enabled. Writing `fair process` ensures that the process (more\nprecisely, each instance of the process template) will eventually\nexecute if it remains enabled. The even stronger condition\n`fair+ process` requires strong fairness for the process, i.e. it will\neventually execute if it is infinitely often enabled---even if it is\nalso infinitely often disabled. For example, a process that requires a\nsemaphore that is infinitely often free will eventually acquire it under\nstrong fairness, even in the presence of competing processes.\n\nThe overall fairness requirement attached to a process can be modulated\nfor individual actions (corresponding to a group of statements\nintroduced by a label). Writing `l:-` instead of `l:` suppresses the\nfairness assumption for the group of statements introduced by label `l`.\nFor example, in a mutual-exclusion algorithm, one may not want to assume\nany fairness condition for the non-critical section. On the contrary,\nwriting `l:+` assumes strong fairness for that group of statements.\n(This has no effect for a strongly fair process.) For example, one may\nin this way require strong fairness only for acquiring a semaphore\nwithin a weakly fair process.\n\nEven finer-grained fairness conditions can be expressed in TLA^+^,\ndetails can be found in the literature on TLA^+^.\n\nTLA^+^\n======\n\nPlusCal algorithms are translated into the TLA^+^ specification\nlanguage, and the TLA^+^ tools (in particular the TLA^+^ Toolbox and the\nmodel checker TLC) are used for verifying properties of algorithms.\nTLA^+^ is based on ordinary mathematical set theory, and it is untyped.\nIn order to effectively use PlusCal, you need to know at least some\nTLA^+^ syntax:\n\n-   all expressions that appear in PlusCal algorithms are written in\n    TLA^+^, and\n\n-   properties to be verified (beyond assertions inserted into PlusCal\n    code) are also written in TLA^+^.\n\nTLA^+^ has ASCII syntax but can be pretty-printed from the Toolbox,\nusing standard mathematical notation. We show the pretty-printed\nversions as well as the ASCII source below.\n\nOverall structure\n-----------------\n\n#### Modules and declarations.\n\nTLA^+^ specifications are structured in *modules*. A TLA^+^ module\nbegins with a header line\n\n`---------- MODULE Name ----------`\n\n(at least four '-' signs) and ends with a bottom line\n\n`=================================`\n\n(at least four '=' signs). A module may import the contents of other\nmodules by [[extend]{.smallcaps}]{.nodecor}ing them, which is basically\nequivalent to copying the content of the extended module into the\nextending module. It may also create [[instance]{.smallcaps}]{.nodecor}s\nof other modules whose (constant or variable) parameters are\ninstantiated by expressions of the instantiating module. This is useful\nfor example when showing that a lower-level specification refines (or\nimplements) a higher-level one.\n\nModules usually declare constant or variable parameters,[^3] for example\n$$\\begin{array}{@{}l}\n    \\textnormal{\\textsc{constants}}\\ \\mathit{Node},\\ \\mathit{Edge}\\\\\n    \\textnormal{\\textsc{variables}}\\ \\mathit{leader}\\ \\mathit{network}\n\\end{array}$$ for declaring constant sets representing the nodes and\nedges of a graph and two variables used in a leader-election algorithm.\n(When the algorithm is written in PlusCal, the variable declaration is\ngenerated by the PlusCal translator.)\n\nSince TLA^+^ is untyped, these declarations do not indicate the types of\nconstants or variables. (Semantically, all TLA^+^ values are sets.)\nHowever, a specification may contain assumptions on the constant\nparameters such as\n$$\\textnormal{\\textsc{assume}}\\ \\mathit{Edge} \\subseteq \\mathit{Node} \\times \\mathit{Node}$$\nand these assumptions are checked by TLC. Properties of variables are\nexpressed using formulas, typically invariants or temporal logic\nproperties.\n\n#### Operator definitions.\n\nThe bulk of a TLA^+^ module consists in operator definitions. Operators\nrepresent subformulas of the overall specification, including useful\noperations on data as well as initial conditions and possible\ntransitions of algorithms. Again, when using PlusCal, most definitions\nare generated by the PlusCal translator. However, a PlusCal algorithm\nmay use operators defined in the TLA^+^ module (or in some extended\nmodule), and correctness properties of a PlusCal algorithm are usually\nspecified in the part of the TLA^+^ module below the generated TLA^+^\ntranslation.\n\nAn operator definition has the form[^4]\n$$\\mathit{op}(p_1, \\dots, p_n)\\ \\,\\mathrel{\\smash{\\stackrel{\\scriptscriptstyle\\Delta}{=}}}\\,\\ e$$\nwhere $p_1, \\dots, p_n$ are parameters of the definition and $e$ is a\nTLA^+^ expression that represents the body of the definition and does\nnot contain $\\mathit{op}$. Each parameter $p_i$ is either an identifier\nor of the form $f(\\_,\\dots,\\_)$. The latter case represents an operator\nparameter, and the number of underscores indicates the arity of the\noperator, i.e. the number of arguments that it expects. For example,\n$$\\mathit{Apply}(f(\\_), x)\\ \\,\\mathrel{\\smash{\\stackrel{\\scriptscriptstyle\\Delta}{=}}}\\,\\ f(x)$$\ntakes a unary operator parameter $f$ and an ordinary parameter $x$.\n\nTLA^+^ enforces the general rule that a name that already exists in the\ncurrent context may not be reused. The above definition of\n$\\mathit{Apply}$ would therefore be illegal in a context where $f$ or\n$x$ have already been introduced as constant or variable parameters or\nas operator names. However, the scope of a parameter symbol is limited\nto the definition in which it appears, and it is therefore legal to\nreuse $x$ as a parameter name in a subsequent definition.\n\n#### Recursive operators.\n\nFor the special case of a function definition, one may write\n$$f[x \\in S] \\,\\mathrel{\\smash{\\stackrel{\\scriptscriptstyle\\Delta}{=}}}\\,e$$\nin order to define a function with domain $S$ that maps every $x \\in S$\nto the expression $e$ (which may contain $x$). In this case, $e$ may\ncontain the symbol $f$. For example, one may write\n$$\\mathit{fact}[n \\in \\mathit{Nat}]\\ \\,\\mathrel{\\smash{\\stackrel{\\scriptscriptstyle\\Delta}{=}}}\\,\\\n  \\begin{array}[t]{@{}l}\n    \\textnormal{\\textsc{if}}\\ n=0\\ \\textnormal{\\textsc{then}}\\ 1\\ \\textnormal{\\textsc{else}}\\ n * \\mathit{fact}[n-1]\n  \\end{array}$$ for defining the factorial function over natural\nnumbers. TLA^+^ also allows for recursive operator definitions; in this\ncase, the names and arities of recursive operators have to be declared\nbefore the definitions, as in $$\\begin{array}{@{}l}\n    \\textnormal{\\textsc{recursive}}\\ \\mathit{Fact}(\\_) \\\\\n    \\mathit{Fact}(n)\\ \\,\\mathrel{\\smash{\\stackrel{\\scriptscriptstyle\\Delta}{=}}}\\,\\ \n    \\textnormal{\\textsc{if}}\\ n=0\\ \\textnormal{\\textsc{then}}\\ 1\\ \\textnormal{\\textsc{else}}\\ n * \\mathit{Fact}(n-1)\n\\end{array}$$ which defines a recursive *operator* (rather than a\nfunction) $\\mathit{Fact}$; note in particular that $\\mathit{Fact}$ does\nnot have a domain. Mutually recursive operators may be introduced by\ndeclaring all operator names and arities before their definitions.\n\n#### Theorems.\n\nFinally, TLA^+^ modules may assert theorems and contain proofs of these\ntheorems. Proofs are checked by the TLA^+^ Proof System (TLAPS), an\ninteractive proof assistant for TLA^+^. Theorems are ignored by TLC:\ninstead, properties to be verified by model checking need to be entered\nin the TLC pane of the TLA^+^ Toolbox. We will therefore not describe\nthe syntax of theorems and proofs here.\n\nLogic\n-----\n\n$\\land,\\ \\lor,\\ \\Rightarrow,\\ \\equiv,\\ \\lnot$\n\n:   `/\\`,  `\\/`,  `=\u003e`,  `\u003c=\u003e`,  `~`\n\n    are the standard operators of propositional logic (conjunction,\n    disjunction, implication, equivalence, and negation).\n\n$=,\\ \\neq$\n\n:   `=`,  `#`\n\n    denote equality and disequality (the latter may also be written\n    `~=`).\n\n$\\textnormal{\\textsc{true}},\\ \\textnormal{\\textsc{false}}$\n\n:   `TRUE`,  `FALSE`\n\n    are the logical constants true and false.\n\n$\\forall x: P(x),\\ \\exists x: P(x)$\n\n:   `\\A x : P(x)`,  `\\E x : P(x)`\n\n    represent the logical quantifiers \"forall\" and \"exists\". You may not\n    reuse a variable that is already used in the current scope. In other\n    words, if $x$ has already been introduced (as a constant, variable,\n    operator or parameter of the current operator definition) then it is\n    illegal to write $\\forall x: P(x)$, but you have to write\n    $\\forall y: P(y)$ for some fresh variable $y$. There exist \"bounded\n    versions\" of the quantifiers restricted to a set $S$ and written as\n    $[\\forall|\\exists] x \\in S: P(x)$, and these are the only forms that\n    TLC can evaluate.\n\n$\\textnormal{\\textsc{choose}}\\ x: P(x)$\n\n:   `CHOOSE x : P(x)`\n\n    denotes some arbitrary but fixed value $x$ such that $P(x)$ is true,\n    and some unspecified fixed value otherwise. Again, there is a\n    bounded version that restricts the choice of possible values to some\n    set $S$, and this is the only form accepted by TLC. In mathematical\n    terminology, this operator is known as \"Hilbert's\n    $\\varepsilon$-operator\". It is important to understand that this\n    represents deterministic choice: multiple evaluations of the\n    expression will yield the same result.\n    [[choose]{.smallcaps}]{.nodecor}-expressions are most useful if\n    there is a unique value satisfying the predicate. For example, the\n    length of a sequence $s$ can be defined as\n    $$\\textnormal{\\textsc{choose}}\\ n \\in \\mathit{Nat}: \\textnormal{\\textsc{domain}}~s = 1\\,..\\,n$$\n    Another useful paradigm is extending some set $S$ by a \"null\n    value\":[^5]\n    $$\\mathit{notAnS}\\ \\,\\mathrel{\\smash{\\stackrel{\\scriptscriptstyle\\Delta}{=}}}\\,\\ \\textnormal{\\textsc{choose}}\\ x: x \\notin S$$\n    The set $S \\cup \\{notAnS\\}$ is then similar to an option type in\n    functional programming.\n\nSets\n----\n\n$\\{e_1, \\dots, e_n\\}$\n\n:   `{e1, ..., en}`\n\n    denotes the set containing (the values corresponding to) the\n    expressions $e_1$, ..., $e_n$. In particular, $\\{\\}$ is the empty\n    set.\n\n$x \\in S,\\ x \\notin S,\\ S \\subseteq T$\n\n:   `x \\in S`,  `x \\notin S`,  `S \\subseteq T`\n\n    is true if $x$ is an element (or is not an element) of set $S$,\n    respectively if $S$ is a subset of $T$.\n\n$\\cup,\\ \\cap,\\ \\setminus$\n\n:   `\\cup` (or `\\union`),  `\\cap` (or `\\inter`),  `\\`\n\n    set union, intersection, and difference.\n\n$\\textnormal{\\textsc{union}}~S$\n\n:   `UNION S`\n\n    generalized set union: $S$ is expected to be a set of sets, and the\n    result is the union of these sets. For example,\n    $\\textnormal{\\textsc{union}}~\\{\\{1,2\\}, \\{3,4\\}\\} =\n      \\{1,2,3,4\\}$, and more generally,\n    $\\textnormal{\\textsc{union}}~\\{A,B\\} = A \\cup B$.\n\n$\\textnormal{\\textsc{subset}}~S$\n\n:   `SUBSET S`\n\n    denotes the set of all subsets of $S$. For example,\n    $$\\textnormal{\\textsc{subset}}~\\{1,2\\} = \\{ \\{\\}, \\{1\\}, \\{2\\}, \\{1,2\\} \\}$$\n\n$\\{x \\in S : P(x)\\}$\n\n:   `{x \\in S : P(x)}`\n\n    denotes the subset of elements of $S$ for which the predicate $P(x)$\n    is true. For example, assuming that $\\mathit{isPrime}(n)$ is true\n    for a natural number $n$ if $n$ is prime then\n    $\\{n \\in 1\\,..\\,100 : \\mathit{isPrime}(n)\\}$ contains the set of\n    prime numbers in the interval between $1$ and $100$.\n\n$\\{e(x) : x \\in S\\}$\n\n:   `{e(x) : x \\in S}`\n\n    denotes the set of values obtained by applying the operator $e$ to\n    all elements of $S$. This construction is similar to the `map`\n    operator from functional programming. For example,\n    $\\{2*n+1 : n \\in 0\\,..\\,99\\}$ denotes the set of the first $100$ odd\n    natural numbers.\n\n$\\mathit{Cardinality}(S)$\n\n:   `Cardinality(S)`\n\n    the number of elements of the finite set $S$. This operator is\n    defined in the module `FiniteSets`, which you must\n    [[extend]{.smallcaps}]{.nodecor} in order to use it. That module\n    also defines the predicate $\\mathit{IsFiniteSet}$ for checking if a\n    set is finite.\n\nFunctions\n---------\n\nTLA^+^ functions are total over their domain. Although every function is\na set (just like any TLA^+^ value), we don't know what set the function\ndenotes and we think of functions as a primitive class of values. (For\nnerds: in many presentations of set theory, functions are sets of pairs.\nThis is not enforced in TLA^+^.) In terms of programming terminology,\nfunctions are analogous to arrays---although their index set or domain\nneed not be finite---and TLA^+^ uses array syntax for functions.\n\n:   `[x \\in S |-\u003e e(x)]`\n\n    denotes the function with domain $S$ that maps every element $x$ of\n    $S$ to $e(x)$. For example, $[n \\in Nat \\mapsto n+1]$ is the\n    successor function on natural numbers. This expression is similar to\n    a $\\lambda$-expression in functional programming.\n\n$\\textnormal{\\textsc{domain}}~f$\n\n:   `DOMAIN f`\n\n    denotes the domain of the function $f$. Although TLA^+^ has no\n    standard notation for the range of a function $f$, it can easily be\n    defined as $$\\{f[x] : x \\in \\textnormal{\\textsc{domain}}~f\\}$$\n\n:   `f[x]`\n\n    denotes the result of applying the function $f$ to the argument $x$.\n    This expression only makes sense if\n    $x \\in \\textnormal{\\textsc{domain}}~f$.\n\n:   `[f EXCEPT ![x] = e]`\n\n    denotes the function that has the same domain as $f$ and acts\n    similarly as $f$, except that it maps the argument $x$ to $e$. For\n    example, if $succ$ is the successor function from above, then\n    $[succ\\ \\textnormal{\\textsc{except}}\\ ![0] = 42]$ is the function\n    that maps every natural number to its successor, but that maps $0$\n    to $42$. Within the expression $e$, one may use the symbol $@$ in\n    order to refer to $f[x]$. For example,\n    $$[\\mathit{count}\\ \\textnormal{\\textsc{except}}\\ ![p] = @+1]$$\n    updates function $\\mathit{count}$ by incrementing\n    $\\mathit{count}[p]$ by $1$.\n\n    Updating a function at several arguments can be written as\n    $$[f\\ \\textnormal{\\textsc{except}}\\ ![x] = a,\\ ![y] = b,\\ ![z] = c]$$\n\n:   `[S -\u003e T]`\n\n    denotes the set of all functions whose domain is $S$ and such that\n    $f[x] \\in\n      T$ holds for all $x \\in S$.\n\nFor functions that take several arguments, TLA^+^ adopts the convention\nthat $f[x,y]$ is shorthand for $f[\\ensuremath{\\langle x,y \\rangle}]$ and\nhence $f \\in [X \\times Y\n\\rightarrow Z]$. This convention extends to\n[[except]{.smallcaps}]{.nodecor} expressions, so you can write\n$[f\\ \\textnormal{\\textsc{except}}\\ ![x,y] = e]$.\n\nRecords\n-------\n\nA TLA^+^ record is a function from a finite set of fields (represented\nas strings) to values. In principle, standard function operations\ntherefore apply to records. Nevertheless, TLA^+^ introduces some\nspecific syntax for records.\n\n:   `[fld1 |-\u003e e1, ..., fldn |-\u003e en]`\n\n    constructs a record with fields $\\mathit{fld}_i$ holding values\n    $e_i$. For example,\n    $$[\\mathit{kind} \\mapsto \\textnormal{\"request\"},\\\n         \\mathit{sndr} \\mapsto p,\\\n         \\mathit{clk} \\mapsto 42]$$ could represent a request message\n    sent by process $p$ with logical clock value 42.\n\n$r.\\mathit{fld}$\n\n:   `r.fld`\n\n    selects the value of field $\\mathit{fld}$ from record $r$.\n\n:   `[r EXCEPT !.fld = e]`\n\n    denotes the record that is similar to $r$, except that field\n    $\\mathit{fld}$ holds value $e$. (The indicated field should exist in\n    record $r$.) An analogous generalization to the\n    [[except]{.smallcaps}]{.nodecor} construct for functions allows\n    several record fields to be updated.\n\nNumbers\n-------\n\nYou must import the arithmetical operators by\n[[extend]{.smallcaps}]{.nodecor}ing one of the standard modules\n`Naturals` or `Integers`. (TLA^+^ also has a standard module `Reals` for\nreal numbers, but we won't need it.)\n\n$\\mathit{Nat},\\ \\mathit{Int}$\n\n:   `Nat`,  `Int`\n\n    denote the set of natural numbers ($0, 1, \\dots$) and of integers.\n\n$i\\,..\\,j$\n\n:   `i .. j`\n\n    an interval of integers, such as `-3 .. 5`.\n\n$+,\\ -,\\ *,\\ \\div,\\ \\mathit{mod}$\n\n:   `+`,  `-`,  `*`,  `\\div`,  `%`\n\n    are the standard arithmetical operations (addition, subtraction,\n    multiplication, integer division and modulus).\n\nTuples and sequences\n--------------------\n\nTuples and sequences are the same mathematical objects, but they are\nused differently: whereas a tuple has a fixed number of components, a\nsequence can be of varying length. In TLA^+^, tuples and sequences are\nrepresented as functions with domain $1\\,..\\,n$, for some natural number\n$n$. (In particular, the empty sequence has domain $1\\,..\\,0$.) Standard\nfunction operations therefore apply, and the $i$-th element of a\nsequence $s$ is obtained as $s[i]$. The sequence operations must be\nimported by [[extend]{.smallcaps}]{.nodecor}ing the standard module\n`Sequences`.\n\n$\\ensuremath{\\langle e_1,\\dots,e_n \\rangle}$\n\n:   `\u003c\u003ce1, ..., en\u003e\u003e`\n\n    denotes the sequence with elements $e_1$, ..., $e_n$, in that order.\n    In particular, `\u003c\u003c \u003e\u003e` is the empty sequence.\n\n$s \\circ t$\n\n:   `s \\o t`\n\n    denotes the concatenation of the sequences $s$ and $t$. For example,\n    $\\ensuremath{\\langle 1,2 \\rangle} \\circ \\ensuremath{\\langle 3,4 \\rangle} = \\ensuremath{\\langle 1,2,3,4 \\rangle}$.\n\n$\\mathit{Seq}(S)$\n\n:   `Seq(S)`\n\n    the set of all finite sequences with elements in set $S$.\n\n$S \\times T$\n\n:   `S \\X T`\n\n    denotes the set product of $S$ and $T$, i.e. the set of all pairs\n    $\\ensuremath{\\langle s,t \\rangle}$ with $s \\in S$ and $t \\in T$.\n\n$\\mathit{Len}(s)$\n\n:   `Len(s)`\n\n    denotes the length of sequence $s$.\n\n$\\mathit{Append}(s,e)$\n\n:   `Append(s,e)`\n\n    adds element $e$ at the end of the sequence $s$.\n\n$\\mathit{Head}(s),\\ \\mathit{Tail}(s)$\n\n:   `Head(s)`,  `Tail(s)`\n\n    denote the first element of the sequence $s$, respectively the rest\n    of the sequence with the first element removed. These operators are\n    well-defined only if the sequence $s$ is non-empty.\n\n$\\mathit{SubSeq}(s,m,n)$\n\n:   `SubSeq(s,m,n)`\n\n    the sequence\n    $\\ensuremath{\\langle s[m], s[m+1], \\dots, s[n] \\rangle}$.\n\n$\\mathit{SelectSeq(s, P(\\_))}$\n\n:   `SelectSeq(s, P(_))`\n\n    denotes the subsequence of elements of sequence $s$ that satisfy\n    predicate $P$. For example, if $\\mathit{isPrime}(n)$ is true if $n$\n    is a prime number, then\n    $$\\mathit{SelectSeq}(\\ensuremath{\\langle 2,3,4,5,6,7,8 \\rangle}, \\mathit{isPrime}) =\n         \\ensuremath{\\langle 2,3,5,7 \\rangle}$$\n\nMany more operators on sequences can easily be defined in TLA^+^. For\nexample, the \"map\" operation on sequences is defined as\n$$\\mathit{Map}(s, f(\\_))\\ \\,\\mathrel{\\smash{\\stackrel{\\scriptscriptstyle\\Delta}{=}}}\\,\\\n  [i \\in \\textnormal{\\textsc{domain}}~s \\mapsto f(s[i])]$$ Other\noperations require recursive definitions, such as a \"reduce\" operation\nthat applies an operation $op$ to all elements of the sequence $s$\nstarting from the \"null value\" $e$: $$\\begin{array}{@{}l}\n    \\textnormal{\\textsc{recursive}}\\ \\mathit{Reduce}(\\_,\\_,\\_)\\\\\n    \\mathit{Reduce}(s, \\mathit{op}(\\_,\\_), e)\\ \\,\\mathrel{\\smash{\\stackrel{\\scriptscriptstyle\\Delta}{=}}}\\,\\\n    \\begin{array}[t]{@{}l}\n      \\textnormal{\\textsc{if}}\\ s = \\ensuremath{\\langle  \\rangle}\\ \\textnormal{\\textsc{then}}\\ e\\\\\n      \\textnormal{\\textsc{else}}\\ \\mathit{op}(\\mathit{Head}(s), \\mathit{Reduce}(\\mathit{Tail}(s), \\mathit{op}, e))\n    \\end{array}\n\\end{array}$$\n\nCharacter strings are represented as sequences of characters. How\ncharacters are represented is left unspecified; literal strings are\nwritten as `\"string\"`. However, TLC handles strings natively and does\nnot support sequence operations applied to strings.\n\nMiscellaneous constructs\n------------------------\n\n$\\textnormal{\\textsc{if}}\\ P\\ \\textnormal{\\textsc{then}}\\ t\\ \\textnormal{\\textsc{else}}\\ e$\n\n:   `IF P THEN t ELSE e`\n\n    is a conditional expression. It can be used as a formula if $t$ and\n    $e$ are both formulas, but also more generally as a term. See the\n    definition of the factorial function earlier for an example.\n\n$\\textnormal{\\textsc{case}}\\ p_1\\ \\rightarrow\\ e_1\\ \\Box\\ p_2\\ \\rightarrow\\ e_2\\ \\dots \\Box\\ \\textnormal{\\textsc{other}}\\ \\rightarrow\\ e$\n\n:   \\\n    `CASE p1 -\u003e e1 [] p2 -\u003e e2 ... [] OTHER -\u003e e`\n\n    generalizes conditional expressions to more than two branches. It\n    equals some $e_i$ such that $p_i$ is true, or $e$ if no guard $p_i$\n    is true (The [[other]{.smallcaps}]{.nodecor} branch is optional.) In\n    case several $p_i$ are true, the choice of which branch is evaluated\n    is fixed but unspecified: make sure that in this case, all\n    corresponding $e_i$ evaluate to the same value.\n\n$\\textnormal{\\textsc{let}}\\ x \\,\\mathrel{\\smash{\\stackrel{\\scriptscriptstyle\\Delta}{=}}}\\,t\\ \\textnormal{\\textsc{in}}\\ e$\n\n:   `LET x == t IN e`\n\n    allows users to introduce local definitions, similar to the standard\n    \"let\" construct of functional programming languages.\n\nOnline Resources\n================\n\n-   [learntla.com](learntla.com): A Web site for helping newcomers learn\n    PlusCal and TLA^+^. There is also a published book (\"Practical\n    TLA^+^\") by the same author with a more complete introduction.\n\n-   \u003chttp://lamport.azurewebsites.net/tla/tla.html\u003e: The official TLA^+^\n    Web site with lots of reference material.\n\n-   \u003chttp://lamport.azurewebsites.net/video/videos.html\u003e: A video course\n    on TLA^+^ by Leslie Lamport (does not cover PlusCal, though).\n\n-   \u003chttp://lamport.azurewebsites.net/tla/c-manual.pdf\u003e: The PlusCal\n    manual for the C syntax that is also used in the lectures.\n\n[^1]: These variables may be initialized using the form $x = v$, but not\n    $x \\in S$.\n\n[^2]: Use of this statement requires [[extend]{.smallcaps}]{.nodecor}ing\n    the standard module TLC.\n\n[^3]: The values of constant parameters remain fixed throughout any\n    execution of the algorithm. TLA^+^ variables are analogous to\n    program variables and assume different values at different states of\n    the execution.\n\n[^4]: The symbol\n    $\\,\\mathrel{\\smash{\\stackrel{\\scriptscriptstyle\\Delta}{=}}}\\,$ is\n    written `==` in ASCII.\n\n[^5]: The astute reader will notice that this form cannot be evaluated\n    by TLC. However, the TLA^+^ Toolbox will substitute a special \"model\n    value\" for $notAnS$.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlaplus%2Fpluscalcheatsheet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftlaplus%2Fpluscalcheatsheet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlaplus%2Fpluscalcheatsheet/lists"}