quint: Tool for the Quint specification language
Revision | Date | Author |
---|---|---|
9 | 2024-06-26 | Igor Konnov, Shon Feder, Gabriela Moreira |
WARNING: This is a preliminary manual in the style of Working Backwards (opens in a new tab). Some commands are not implemented yet.
quint
is a command line interface tool for working with the Quint
specification language. It is the primary access point for testing
and integration with other tools.
The main commands of quint
are as follows:
-
repl
starts the REPL (Read-Eval-Print loop) for Quint -
compile
parses, typechecks, and processes a quint specification into the--target
format, writing the results to stdout -
parse
parses a Quint specification and resolves names -
typecheck
infers types in a Quint specification -
run
executes a Quint specification via random simulation similar to stateful property-based testing -
test
runs unit tests against a Quint specification -
verify
verifies a Quint specification with Apalache -
docs
produces documentation -
lint
checks a Quint specification for known deficiencies -
indent
indents a Quint specification
In the following, we give details about the above commands.
Installation
npm i @informalsystems/quint -g
Command repl
This is the default operation if no other subcommand is given:
$ quint
You can also invoke it directly with quint repl
:
$ quint repl --help
quint repl
run an interactive Read-Evaluate-Print-Loop
Options:
--help Show help [boolean]
--version Show version number [boolean]
-r, --require filename[::module]. Preload the file and, optionally, import
the module [string]
--verbosity control how much output is produced (0 to 5)
[number] [default: 2]
quint repl
The REPL is especially useful for learning the language. See the repl documentation for more details.
The verbosity levels 3 and 4 are used to show execution details. They are especially useful for debugging complex specifications.
Command compile
$ quint compile --help
quint compile <input>
compile a Quint specification into the target, the output is written to stdout
Options:
--help Show help [boolean]
--version Show version number [boolean]
--out output file (suppresses all console output) [string]
--main name of the main module (by default, computed from filename)
[string]
--init name of the initializer action [string] [default: "init"]
--step name of the step action [string] [default: "step"]
--invariant the invariants to check, separated by commas (e.g.) [string]
--temporal the temporal properties to check, separated by commas [string]
--target the compilation target. Supported values: tlaplus, json
[string] [default: "json"]
--verbosity control how much output is produced (0 to 5)[number] [default: 2]
Given a quint specification as input, this command parses, resolves imports, typechecks, and then "flattens" the specification into on module containing just the needed definitions.
The main module is determined as follows: If a module name is specified by
--main
, that takes precedence. Otherwise, if there is only one module in the
input file, that is the main module. Otherwise, the module with the same name as
the file is taken to be the main module.
The main module must specify a state machine. This means it must either define
actions named init
and step
, specifying the initial state and the
transition action respectively, or suitable actions defined in the main module
must be indicated using the --init
and --step
options.
The following compilation targets are supported
json
: The default target, this produces a json representation, in the same format which is described underparse
andtypecheck
, below.tlaplus
: Quint uses its integration with Apalache to compile the specification into TLA+.
Command parse
Warning: The language is still in active development, and breaking changes are to be expected.
$ quint parse --help
quint parse <input>
parse a Quint specification
Options:
--help Show help [boolean]
--version Show version number [boolean]
--out output file [string]
--source-map name of the source map [string]
This command reads a Quint specification from the file <spec>.qnt
, parses the
specification and resolves the imports relative to the directory of
<spec>.qnt
. If the command produces errors, these errors are printed on
stderr
. If there are no errors, nothing is printed.
If the user supplies the flag --out
, then the
parsing result is written to the file <out>.json
. Depending on the outcome,
the following is written:
-
If the command succeeds, the file contains the parsed and resolved module in Quint IR (opens in a new tab) (JSON):
{ "stage": "parsing", "module": <IR>, "warnings": [ <warnings> ] }
The module contents is the JSON representation of Quint IR (opens in a new tab). The warnings are written in the format of ADR002.
-
If the command fails, the file contains an error message in JSON:
{ "stage": "parsing", "errors": [ <errors> ] }
The errors and warnings are written in the format of ADR002.
Command typecheck
quint typecheck [--out=<out>.json] <spec>.qnt
This command infers types in the Quint specification, which is provided in the
input file <spec>.qnt
. Before doing that, it performs the same steps as the
command parse
. If the command produces errors, these errors are printed on
stderr
. If there are no errors, nothing is printed.
Option --out
. If the user supplies the flag --out
, then the
parsing result is written to the file <out>.json
. Depending on the outcome,
the following is written:
-
If the command succeeds, the file contains the parsed and resolved module in Quint IR (opens in a new tab) (JSON):
{ "stage": "typechecking", "module": <IR>, "types": { <typemap> } "effects": { <effectmap> } }
The module contents is the JSON representation of Quint IR (opens in a new tab), the
types
andeffects
map source IDs of entities in themodule
to their inferred type or effect. -
If the command fails, the file contains an error message in JSON:
{ "stage": "typechecking", "errors": [ <errors> ] }
The errors and warnings are written in the format of ADR002.
Command run
$ quint run --help
quint run <input>
Simulate a Quint specification and (optionally) check invariants
Options:
--help Show help [boolean]
--version Show version number [boolean]
--main name of the main module (by default, computed from filename)
[string]
--out output file (suppresses all console output) [string]
--out-itf output the trace in the Informal Trace Format to file
(suppresses all console output) [string]
--max-samples the maximum on the number of traces to try
[number] [default: 10000]
--n-traces how many traces to generate (only affects output to out-itf)
[number] [default: 1]
--max-steps the maximum on the number of steps in every trace
[number] [default: 20]
--init name of the initializer action [string] [default: "init"]
--step name of the step action [string] [default: "step"]
--invariant invariant to check: a definition name or an expression
[string] [default: ["true"]]
--seed random seed to use for non-deterministic choice [string]
--mbt (experimental) whether to produce metadata to be used by
model-based testing [boolean] [default: false]
-
If there are no critical errors (e.g., in parsing, typechecking, etc.), the simulator tries to find the shortest trace that violates the invariant. If it finds one, it prints the trace on the standard output. If it does not find a violating trace, it prints the longest sample trace that the simulator has found during the execution. When the parameter
--out
is supplied, the trace is written as a JSON representation of Quint IR in the output file. When the parameter--out-itf
is supplied, the traces are written in the Informal Trace Format (opens in a new tab). This output can be conviently displayed with the ITF Trace Viewer (opens in a new tab), or just with jq (opens in a new tab). -
If the specification cannot be run (e.g., due to a parsing error), the file contains an error message in JSON:
{ "stage": "running", "errors": [ <errors> ] }
The errors and warnings are written in the format of ADR002.
The --mbt
flag
When this flag is given, the Quint simulator will keep track of two additional variables on the traces it produces:
action_taken
: The first action executed by the simulator on each step, reset at everyany
evaluation. That is, if the spec has nestedany
statements,action_taken
will correspond to the action picked in the innermostany
.nondet_picks
: A record with allnondet
values that were picked since the lastany
was called (or since the start, if there were noany
calls in the step).
Keep in mind that this is an experimental flag and it is specially subject to changes in its behavior.
Command test
$ quint test --help
quint test <input>
Run tests against a Quint specification
Options:
--help Show help [boolean]
--version Show version number [boolean]
--main name of the main module (by default, computed from filename)
[string]
--out output file (suppresses all console output) [string]
--max-samples the maximum number of successful runs to try for every
randomized test [number] [default: 10000]
--seed random seed to use for non-deterministic choice [string]
--verbosity control how much output is produced (0 to 5)[number] [default: 2]
--match a string or regex that selects names to use as tests [string]
-
If there are no critical errors (e.g., in parsing, typechecking, etc.), the command succeeds. The output file contains the parsed and resolved module in Quint IR (opens in a new tab) (JSON):
{ "stage": "testing", "passed": [ <names of the successful tests> ], "failed": [ <names of the failed tests> ], "ignored": [ <names of the ignored tests> ], "errors": [ <errors and warnings> ] }
-
If the tests cannot be run (e.g., due to a parsing error), the file contains an error message in JSON:
{ "stage": "testing", "errors": [ <errors and warnings> ] }
The errors and warnings are written in the format of ADR002.
Command verify
$ quint verify --help
quint verify <input>
Verify a Quint specification via Apalache
Options:
--help Show help [boolean]
--version Show version number [boolean]
--out output file (suppresses all console output) [string]
--main name of the main module (by default, computed from
filename) [string]
--init name of the initializer action[string] [default: "init"]
--step name of the step action [string] [default: "step"]
--invariant the invariants to check, separated by commas (e.g.)
[string]
--temporal the temporal properties to check, separated by commas
[string]
--out-itf output the trace in the Informal Trace Format to file
(suppresses all console output) [string]
--max-steps the maximum number of steps in every trace
[number] [default: 10]
--random-transitions choose transitions at random (= use symbolic simulation)
[boolean] [default: false]
--apalache-config path to an additional Apalache configuration file (in
JSON) [string]
--verbosity control how much output is produced (0 to 5)
[number] [default: 2]
By default, this command will automatically obtain and run Apalache. The only prerequisite is a compatible installation of OpenJDK.
You may also manually obtain and run a distribution of Apalache, following these steps:
- Install a distribution of Apalache (opens in a new tab).
- Start the Apalache server
apalache-mc server
and ensure that it is running.
Apalache uses bounded model checking. This technique checks all runs up to
--max-steps
steps via z3 (opens in a new tab). Apalache is highly configurable. See Apalache
configuration (opens in a new tab)
for guidance.
-
If there are no critical errors (e.g., in parsing, typechecking, etc.), this command sends the Quint specification to the Apalache (opens in a new tab) model checker, which will try to find an invariant violation. If it finds one, it prints the trace on the standard output. When the parameter
--out
is supplied, the trace is written as a JSON representation of Quint IR in the output file. When the parameter--out-itf
is supplied, the trace is written in the Informal Trace Format (opens in a new tab). This output can be conveniently displayed with the ITF Trace Viewer (opens in a new tab), or just with jq (opens in a new tab). -
If the specification cannot be run (e.g., due to a parsing error), the file contains an error message in JSON:
{ "stage": "verifying", "errors": [ <errors> ] }
The errors and warnings are written in the format of ADR002.
Command lint
This command is not implemented yet.
quint lint [--config=config.json] [--out=<out>.json] <spec>.qnt
This command checks an input specification <spec>.qnt
against a set of rules.
If no errors or warnings are found, this command outputs nothing.
When errors or warning are found, this command outputs them to stderr
,
unless the command --out
is specified.
Option --config
. This parameter specifies a configuration file in the
JSON format. This configuration files specifies linting rules. The exact format
is to be specified in the future.
Option --out
. If the user supplies the flag --out
, then the
result is written to the file <out>.json
. Depending on the outcome,
the following is written:
-
If the command succeeds, the file contains the success data structure:
{ "status": "linted" }
-
If the command fails, the file contains error messages and warnings in JSON:
{ "result": "error", "messages": [ <errors and warnings> ] }
The errors and warnings are written in the format of ADR002.
Command indent
This command is not implemented yet.
quint indent [--config=config.json] [--out=<out>.qnt] <spec>.qnt
This rule formats the input specification according to the default indentation
rules. Unless the option --out
is specified, the formatted specification
is written on the standard output.
Option --out
. The optional parameter --out
specifies the name of
an output file in the Quint format.
Option --config
. This parameter specifies a configuration file in the
JSON format. This configuration files specifies the indentation rules. The
exact format is to be specified in the future.