Skip to content

Commit 401ca15

Browse files
authored
Merge branch 'main' into gabriela/type-quantification-fix
2 parents f695cb8 + cb460f3 commit 401ca15

File tree

5 files changed

+231
-136
lines changed

5 files changed

+231
-136
lines changed

doc/quint.md

+34-19
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,18 @@ especially useful for debugging complex specifications.
7373
$ quint compile --help
7474
quint compile <input>
7575

76-
compile a Quint specification into the target, the output is written to
77-
stdout
76+
compile a Quint specification into the target, the output is written to stdout
7877

7978
Options:
8079
--help Show help [boolean]
8180
--version Show version number [boolean]
8281
--out output file (suppresses all console output) [string]
8382
--main name of the main module (by default, computed from filename)
8483
[string]
84+
--init name of the initializer action [string] [default: "init"]
85+
--step name of the step action [string] [default: "step"]
86+
--invariant the invariants to check, separated by commas (e.g.) [string]
87+
--temporal the temporal properties to check, separated by commas [string]
8588
--target the compilation target. Supported values: tlaplus, json
8689
[string] [default: "json"]
8790
--verbosity control how much output is produced (0 to 5)[number] [default: 2]
@@ -91,6 +94,16 @@ Given a quint specification as input, this command parses, resolves imports,
9194
typechecks, and then "flattens" the specification into on module containing just
9295
the needed definitions.
9396

97+
The main module is determined as follows: If a module name is specified by
98+
`--main`, that takes precedence. Otherwise, if there is only one module in the
99+
input file, that is the main module. Otherwise, the module with the same name as
100+
the file is taken to be the main module.
101+
102+
The main module must specify a state machine. This means it must either define
103+
actions named `init` and `step`, specifying the initial state and the
104+
transition action respectively, or suitable actions defined in the main module
105+
must be indicated using the `--init` and `--step` options.
106+
94107
The following compilation targets are supported
95108

96109
- `json`: The default target, this produces a json representation, in the same
@@ -105,7 +118,7 @@ The following compilation targets are supported
105118
to be expected.*
106119

107120
```sh
108-
$ quint parse --help
121+
$ quint parse --help
109122
quint parse <input>
110123

111124
parse a Quint specification
@@ -292,30 +305,32 @@ Options:
292305
## Command verify
293306
294307
```sh
295-
$ quint verify <input>
308+
$ quint verify --help
309+
quint verify <input>
296310

297311
Verify a Quint specification via Apalache
298312

299313
Options:
300-
--help Show help [boolean]
301-
--version Show version number [boolean]
302-
--main name of the main module (by default, computed from
303-
filename) [string]
304-
--out output file (suppresses all console output) [string]
305-
--out-itf output the trace in the Informal Trace Format to file
306-
(suppresses all console output) [string]
307-
--max-steps the maximum number of steps in every trace
308-
[number] [default: 10]
309-
--init name of the initializer action [string] [default: "init"]
310-
--step name of the step action [string] [default: "step"]
311-
--invariant the invariants to check, separated by a comma [string]
312-
--temporal the temporal properties to check, separated by a comma
314+
--help Show help [boolean]
315+
--version Show version number [boolean]
316+
--out output file (suppresses all console output) [string]
317+
--main name of the main module (by default, computed from
318+
filename) [string]
319+
--init name of the initializer action[string] [default: "init"]
320+
--step name of the step action [string] [default: "step"]
321+
--invariant the invariants to check, separated by commas (e.g.)
313322
[string]
323+
--temporal the temporal properties to check, separated by commas
324+
[string]
325+
--out-itf output the trace in the Informal Trace Format to file
326+
(suppresses all console output) [string]
327+
--max-steps the maximum number of steps in every trace
328+
[number] [default: 10]
314329
--random-transitions choose transitions at random (= use symbolic simulation)
315330
[boolean] [default: false]
316331
--apalache-config path to an additional Apalache configuration file (in
317332
JSON) [string]
318-
--verbosity control how much output is produced (0 to 5)
333+
--verbosity control how much output is produced (0 to 5)
319334
[number] [default: 2]
320335
```
321336
@@ -332,7 +347,7 @@ steps:
332347
Apalache uses bounded model checking. This technique checks *all runs* up to
333348
`--max-steps` steps via [z3][]. Apalache is highly configurable. See [Apalache
334349
configuration](https://apalache.informal.systems/docs/apalache/config.html?highlight=configuration#apalache-configuration)
335-
for guidance.
350+
for guidance.
336351
337352
- If there are no critical errors (e.g., in parsing, typechecking, etc.), this
338353
command sends the Quint specification to the [Apalache][] model checker, which

quint/apalache-tests.md

+64-5
Original file line numberDiff line numberDiff line change
@@ -239,18 +239,24 @@ VARIABLE x
239239
240240
A == Variant("A", "U_OF_UNIT")
241241
242-
B(__BParam_27) == Variant("B", __BParam_27)
242+
B(__BParam_31) == Variant("B", __BParam_31)
243243
244-
foo_bar(id__123_31) == id__123_31
244+
foo_bar(id__123_35) == id__123_35
245245
246246
importedValue == 0
247247
248248
ApalacheCompilation_ModuleToInstantiate_C == 0
249249
250+
altInit == x' := 0
251+
250252
step == x' := (x + 1)
251253
254+
altStep == x' := (x + 0)
255+
252256
inv == x >= 0
253257
258+
altInv == x >= 0
259+
254260
ApalacheCompilation_ModuleToInstantiate_instantiatedValue ==
255261
ApalacheCompilation_ModuleToInstantiate_C
256262
@@ -259,6 +265,55 @@ init ==
259265
:= (importedValue
260266
+ ApalacheCompilation_ModuleToInstantiate_instantiatedValue)
261267
268+
q_step == step
269+
270+
q_init == init
271+
272+
================================================================================
273+
```
274+
275+
### Test that we can compile to TLA+ of the expected form with CLI configs
276+
277+
We check that specifying `--init`, `--step`, and `--invariant` work as expected
278+
279+
<!-- !test in can convert ApalacheCompliation.qnt to TLA+ with CLI config -->
280+
```
281+
quint compile --target tlaplus \
282+
--init altInit --step altStep --invariant altInv \
283+
./testFixture/ApalacheCompilation.qnt \
284+
| grep -e q_init -e q_step -e q_inv
285+
```
286+
287+
<!-- !test out can convert ApalacheCompliation.qnt to TLA+ with CLI config -->
288+
```
289+
q_init == altInit
290+
q_step == altStep
291+
q_inv == altInv
292+
```
293+
294+
### Test that we can compile to TLA+ of the expected form, specifying `--main`
295+
296+
<!-- !test in can convert ApalacheCompliation.qnt to TLA+ with alt main -->
297+
```
298+
quint compile --target tlaplus --main ModuleToImport ./testFixture/ApalacheCompilation.qnt
299+
```
300+
301+
<!-- !test out can convert ApalacheCompliation.qnt to TLA+ with alt main -->
302+
```
303+
---------------------------- MODULE ModuleToImport ----------------------------
304+
305+
EXTENDS Integers, Sequences, FiniteSets, TLC, Apalache, Variants
306+
307+
step == TRUE
308+
309+
importedValue == 0
310+
311+
init == TRUE
312+
313+
q_init == init
314+
315+
q_step == step
316+
262317
================================================================================
263318
```
264319

@@ -270,14 +325,18 @@ init ==
270325
quint compile --target tlaplus ../examples/classic/distributed/ClockSync/clockSync3.qnt | head
271326
```
272327

328+
The compiled module is not empty:
273329

274-
TODO: This is an incorrect result, we are removing all "unused" declarations
275-
which leaves nothing, thanks to the way clockSync3 is instanced.
276330
<!-- !test out can convert clockSync3.qnt to TLA+ -->
277331
```
278332
------------------------------ MODULE clockSync3 ------------------------------
279333
280334
EXTENDS Integers, Sequences, FiniteSets, TLC, Apalache, Variants
281335
282-
================================================================================
336+
VARIABLE clockSync3_clockSync3Spec_time
337+
338+
clockSync3_clockSync3Spec_Proc(clockSync3_clockSync3Spec_id_37) ==
339+
[id |-> clockSync3_clockSync3Spec_id_37]
340+
341+
VARIABLE clockSync3_clockSync3Spec_hc
283342
```

quint/src/cli.ts

+41-36
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
compile,
1818
docs,
1919
load,
20+
outputCompilationTarget,
2021
outputResult,
2122
parse,
2223
runRepl,
@@ -36,6 +37,32 @@ const defaultOpts = (yargs: any) =>
3637
type: 'string',
3738
})
3839

40+
// Arguments used by routines that pass thru the `compile` stage
41+
const compileOpts = (yargs: any) =>
42+
defaultOpts(yargs)
43+
.option('main', {
44+
desc: 'name of the main module (by default, computed from filename)',
45+
type: 'string',
46+
})
47+
.option('init', {
48+
desc: 'name of the initializer action',
49+
type: 'string',
50+
default: 'init',
51+
})
52+
.option('step', {
53+
desc: 'name of the step action',
54+
type: 'string',
55+
default: 'step',
56+
})
57+
.option('invariant', {
58+
desc: 'the invariants to check, separated by commas (e.g.)',
59+
type: 'string',
60+
})
61+
.option('temporal', {
62+
desc: 'the temporal properties to check, separated by commas',
63+
type: 'string',
64+
})
65+
3966
// Chain async CLIProcedures
4067
//
4168
// This saves us having to manually thread the result argument like
@@ -77,11 +104,7 @@ const compileCmd = {
77104
command: 'compile <input>',
78105
desc: 'compile a Quint specification into the target, the output is written to stdout',
79106
builder: (yargs: any) =>
80-
defaultOpts(yargs)
81-
.option('main', {
82-
desc: 'name of the main module (by default, computed from filename)',
83-
type: 'string',
84-
})
107+
compileOpts(yargs)
85108
.option('target', {
86109
desc: `the compilation target. Supported values: ${supportedTarges.join(', ')}`,
87110
type: 'string',
@@ -99,7 +122,12 @@ const compileCmd = {
99122
default: verbosity.defaultLevel,
100123
}),
101124
handler: (args: any) =>
102-
load(args).then(chainCmd(parse)).then(chainCmd(typecheck)).then(chainCmd(compile)).then(outputResult),
125+
load(args)
126+
.then(chainCmd(parse))
127+
.then(chainCmd(typecheck))
128+
.then(chainCmd(compile))
129+
.then(chainCmd(outputCompilationTarget))
130+
.then(outputResult),
103131
}
104132

105133
// construct repl commands with yargs
@@ -235,15 +263,7 @@ const verifyCmd = {
235263
command: 'verify <input>',
236264
desc: `Verify a Quint specification via Apalache`,
237265
builder: (yargs: any) =>
238-
yargs
239-
.option('main', {
240-
desc: 'name of the main module (by default, computed from filename)',
241-
type: 'string',
242-
})
243-
.option('out', {
244-
desc: 'output file (suppresses all console output)',
245-
type: 'string',
246-
})
266+
compileOpts(yargs)
247267
.option('out-itf', {
248268
desc: 'output the trace in the Informal Trace Format to file (suppresses all console output)',
249269
type: 'string',
@@ -253,26 +273,6 @@ const verifyCmd = {
253273
type: 'number',
254274
default: 10,
255275
})
256-
.option('init', {
257-
desc: 'name of the initializer action',
258-
type: 'string',
259-
default: 'init',
260-
})
261-
.option('step', {
262-
desc: 'name of the step action',
263-
type: 'string',
264-
default: 'step',
265-
})
266-
.option('invariant', {
267-
desc: 'the invariants to check, separated by a comma',
268-
type: 'string',
269-
coerce: (s: string) => s.split(','),
270-
})
271-
.option('temporal', {
272-
desc: 'the temporal properties to check, separated by a comma',
273-
type: 'string',
274-
coerce: (s: string) => s.split(','),
275-
})
276276
.option('random-transitions', {
277277
desc: 'choose transitions at random (= use symbolic simulation)',
278278
type: 'boolean',
@@ -295,7 +295,12 @@ const verifyCmd = {
295295
// type: 'number',
296296
// })
297297
handler: (args: any) =>
298-
load(args).then(chainCmd(parse)).then(chainCmd(typecheck)).then(chainCmd(verifySpec)).then(outputResult),
298+
load(args)
299+
.then(chainCmd(parse))
300+
.then(chainCmd(typecheck))
301+
.then(chainCmd(compile))
302+
.then(chainCmd(verifySpec))
303+
.then(outputResult),
299304
}
300305

301306
// construct documenting commands with yargs

0 commit comments

Comments
 (0)