Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always show the seed on simulation #1524

Merged
merged 4 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Deprecated
### Removed
### Fixed

- The seed was not being properly printed when the simulator found some runtime errors (#1524).

### Security

## v0.22.1 -- 2024-09-25
Expand Down
17 changes: 10 additions & 7 deletions quint/io-cli-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ in the lookup table for the expression with ID 7:

<!-- !test in type and effect maps are output -->
```
quint typecheck --out typecheck-out-example.json ../examples/language-features/tuples.qnt > /dev/null
quint typecheck --out typecheck-out-example.json ../examples/language-features/tuples.qnt
printf "first type: " && cat typecheck-out-example.json | jq '.types."7".type.kind'
printf "first effect: " && cat typecheck-out-example.json | jq '.effects."8".effect.kind'
rm typecheck-out-example.json
Expand Down Expand Up @@ -443,8 +443,8 @@ An example execution:
[State 4] { n: 12 }

[violation] Found an issue (duration).
Use --seed=0x308623f2a48e7 to reproduce.
Use --verbosity=3 to show executions.
Use --seed=0x308623f2a48e7 to reproduce.
error: Invariant violated
```

Expand Down Expand Up @@ -477,8 +477,8 @@ An example execution:
[State 4] { action_taken: "OnDivByThree", n: 12, nondet_picks: { } }

[violation] Found an issue (duration).
Use --seed=0x308623f2a48e7 to reproduce.
Use --verbosity=3 to show executions.
Use --seed=0x308623f2a48e7 to reproduce.
error: Invariant violated
```

Expand Down Expand Up @@ -508,9 +508,9 @@ An example execution:
[State 4] { n: 12 }

[ok] No violation found (duration).
Use --seed=0x11 to reproduce.
You may increase --max-samples and --max-steps.
Use --verbosity to produce more (or less) output.
Use --seed=0x11 to reproduce.
```

### Repl evaluates coin
Expand Down Expand Up @@ -589,8 +589,8 @@ An example execution:
}

[violation] Found an issue (duration).
Use --seed=0x1e352e160ffbb3 to reproduce.
Use --verbosity=3 to show executions.
Use --seed=0x1e352e160ffbb3 to reproduce.
error: Invariant violated
```

Expand Down Expand Up @@ -721,8 +721,8 @@ q::stepAndInvariant => false
}

[violation] Found an issue (duration).
Use --seed=0x1786e678d460fe to reproduce.
Use --verbosity=3 to show executions.
Use --seed=0x1786e678d460fe to reproduce.
error: Invariant violated
```

Expand Down Expand Up @@ -1164,9 +1164,11 @@ error: Tests failed

### Fail on run with uninitialized constants

FIXME: this should not be a runtime error

<!-- !test in run uninitialized -->
```
output=$(quint run testFixture/_1041compileConst.qnt 2>&1)
output=$(quint run testFixture/_1041compileConst.qnt --seed=1 2>&1)
exit_code=$?
echo "$output" | sed -e 's/([0-9]*ms)/(duration)/g' \
-e 's#^.*_1041compileConst.qnt#HOME/_1041compileConst.qnt#g'
Expand All @@ -1180,6 +1182,7 @@ HOME/_1041compileConst.qnt:5:24 - error: [QNT500] Uninitialized const N. Use: im
5: action init = { x' = N }
^

Use --seed=0x1 to reproduce.
error: Runtime error
```

Expand Down
19 changes: 14 additions & 5 deletions quint/src/cliCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ interface OutputStage {
// Possible results from 'run'
status?: 'ok' | 'violation' | 'failure' | 'error'
trace?: QuintEx[]
seed?: bigint
/* Docstrings by definition name by module name */
documentation?: Map<string, Map<string, DocumentationEntry>>
errors?: ErrorMessage[]
Expand All @@ -104,6 +105,7 @@ const pickOutputStage = ({
ignored,
status,
trace,
seed,
}: ProcedureStage) => {
return {
stage,
Expand All @@ -119,6 +121,7 @@ const pickOutputStage = ({
ignored,
status,
trace,
seed,
}
}

Expand Down Expand Up @@ -567,6 +570,10 @@ export async function runSimulator(prev: TypecheckedStage): Promise<CLIProcedure
? { status: (evalResult.value as QuintBool).value ? 'ok' : 'violation' }
: { status: 'error', errors: [evalResult.value] }

const states = recorder.bestTraces[0]?.frame?.args?.map(e => e.toQuintEx(zerog))
const frames = recorder.bestTraces[0]?.frame?.subframes
simulator.seed = recorder.bestTraces[0]?.seed

recorder.bestTraces.forEach((trace, index) => {
const maybeEvalResult = trace.frame.result
if (maybeEvalResult.isLeft()) {
Expand All @@ -584,9 +591,6 @@ export async function runSimulator(prev: TypecheckedStage): Promise<CLIProcedure
options.onTrace(index, status, evaluator.varNames(), states)
})

const states = recorder.bestTraces[0]?.frame?.args?.map(e => e.toQuintEx(zerog))
const frames = recorder.bestTraces[0]?.frame?.subframes
const seed = recorder.bestTraces[0]?.seed
switch (outcome.status) {
case 'error':
return cliErr('Runtime error', {
Expand All @@ -600,7 +604,6 @@ export async function runSimulator(prev: TypecheckedStage): Promise<CLIProcedure
maybePrintCounterExample(verbosityLevel, states, frames)
if (verbosity.hasResults(verbosityLevel)) {
console.log(chalk.green('[ok]') + ' No violation found ' + chalk.gray(`(${elapsedMs}ms).`))
console.log(chalk.gray(`Use --seed=0x${seed.toString(16)} to reproduce.`))
if (verbosity.hasHints(verbosityLevel)) {
console.log(chalk.gray('You may increase --max-samples and --max-steps.'))
console.log(chalk.gray('Use --verbosity to produce more (or less) output.'))
Expand All @@ -617,7 +620,6 @@ export async function runSimulator(prev: TypecheckedStage): Promise<CLIProcedure
maybePrintCounterExample(verbosityLevel, states, frames)
if (verbosity.hasResults(verbosityLevel)) {
console.log(chalk.red(`[violation]`) + ' Found an issue ' + chalk.gray(`(${elapsedMs}ms).`))
console.log(chalk.gray(`Use --seed=0x${seed.toString(16)} to reproduce.`))

if (verbosity.hasHints(verbosityLevel)) {
console.log(chalk.gray('Use --verbosity=3 to show executions.'))
Expand Down Expand Up @@ -866,21 +868,28 @@ export async function docs(loaded: LoadedStage): Promise<CLIProcedure<Documentat
export function outputResult(result: CLIProcedure<ProcedureStage>) {
result
.map(stage => {
const verbosityLevel = deriveVerbosity(stage.args)
const outputData = pickOutputStage(stage)
if (stage.args.out) {
writeToJson(stage.args.out, outputData)
} else if (!stage.args.outItf && outputData.seed && verbosity.hasResults(verbosityLevel)) {
console.log(chalk.gray(`Use --seed=0x${outputData.seed.toString(16)} to reproduce.`))
}

process.exit(0)
})
.mapLeft(({ msg, stage }) => {
const { args, errors, sourceCode } = stage
const verbosityLevel = deriveVerbosity(args)
const outputData = pickOutputStage(stage)
if (args.out) {
writeToJson(args.out, outputData)
} else {
const finders = createFinders(sourceCode!)
uniqWith(errors, isEqual).forEach(err => console.error(formatError(sourceCode, finders, err)))
if (!stage.args.outItf && outputData.seed && verbosity.hasResults(verbosityLevel)) {
console.log(chalk.gray(`Use --seed=0x${outputData.seed.toString(16)} to reproduce.`))
}
console.error(`error: ${msg}`)
}
process.exit(1)
Expand Down
Loading