@informalsystems/quint
Version:
Core tool for the Quint specification language
144 lines (143 loc) • 5.38 kB
TypeScript
import { QuintApp } from '../ir/quintIr';
import { Rng } from './../rng';
import { Either } from '@sweet-monads/either';
import { QuintError } from '../quintError';
import { RuntimeValue } from './impl/runtimeValue';
/**
* A snapshot of how a single operator (e.g., an action) was executed.
* In stack-based languages, this usually corresponds to a stack frame.
* In Quint, it is simply the applied operator and the arguments.
*
* In addition to that, we use a top-level execution frame to represent
* the execution history:
*
* - `subframes` stores the executed actions, e.g., `init` and `step`
* - `result` stores the result of the overall computation:
* just(false), just(true), or none().
* - `args` stores the visited states. Note that |subframes| = |args|.
* - `app` is a dummy operator, e.g., an empty record.
*/
export interface ExecutionFrame {
/**
* The operator that was applied in this frame.
*/
app: QuintApp;
/**
* The actual runtime values that were used in the call.
*/
args: RuntimeValue[];
/**
* An optional result of the execution.
*/
result: Either<QuintError, RuntimeValue>;
/**
* The frames of the operators that were called by this operator.
*/
subframes: ExecutionFrame[];
}
export interface Trace {
frame: ExecutionFrame;
seed: bigint;
}
/**
* A listener that receives events in the course of Quint evaluation.
* This listener may be used to collect a trace, or to record profiling data.
*/
export interface ExecutionListener {
/**
* This callback is called whenever a user-defined operator is called.
*
* @param app operator application in Quint IR
*/
onUserOperatorCall(app: QuintApp): void;
/**
* This callback is called whenever a user-defined operator returns
* from its evaluation. Note that it is the runtime's obligation to
* balance the Call and Return events.
*
* @param app operator application in Quint IR
* @param args the actual arguments obtained in evaluation
* @param result optional result of the evaluation
*/
onUserOperatorReturn(app: QuintApp, args: RuntimeValue[], result: Either<QuintError, RuntimeValue>): void;
/**
* This callback is called *before* one of the arguments of `any {...}`
* is evaluated. This is a very important call, as it introduces a
* branching point in the execution.
*
* @param anyExpr the expression `any { ... }` that contains the option
* @param position the position of the option in `anyExpr.args`
*/
onAnyOptionCall(anyExpr: QuintApp, position: number): void;
/**
* This callback is called *after* one of the arguments of `any {...}`
* is evaluated. Note that it is the runtime's
* obligation to balance the Call and Return events.
*
* @param anyExpr the expression `any { ... }` that contains the option
* @param position the position of the option in `anyExpr.args`
*/
onAnyOptionReturn(anyExpr: QuintApp, position: number): void;
/**
* This callback is called when leaving `any { A_1, ..., A_n }`.
* It instructs the listener to discard the top `noptions` records
* except the one in the `choice` position.
*
* @param noptions the number of translated options, that is, `n`.
* @param choice is a number between -1 and n (exclusive),
* where -1 means that no option was chosen (discard all).
*/
onAnyReturn(noptions: number, choice: number): void;
/**
* This callback is called whenever an execution proceeds to the next state,
* e.g., once A has been evaluated in A.then(B).
* @param oldState the old state that is about to be discarded
* @param newState the new state, from which the execution continues
*/
onNextState(oldState: RuntimeValue, newState: RuntimeValue): void;
/**
* This callback is called when a new run is executed,
* e.g., when multiple runs are executed in the simulator.
*/
onRunCall(): void;
/**
* This callback is called when the previous run has finished.
*
* @param outcome whether the run has:
* - failed, that is, `none()`,
* - finished after finding no violation, `just(mkBool(true))`,
* - finished after finding a violation, `just(mkBool(false))`
* @param trace the array of produced states (each state is a record)
*/
onRunReturn(outcome: Either<QuintError, RuntimeValue>, trace: RuntimeValue[]): void;
}
/**
* An implementation of ExecutionListener that does nothing.
*/
export declare const noExecutionListener: ExecutionListener;
/**
* The interface of a trace recorder that records the best trace.
*/
export interface TraceRecorder extends ExecutionListener {
/**
* The verbosity level used by the recorder (mutable).
*/
verbosityLevel: number;
/**
* The random number generator used by the recorder (mutable).
*/
rng: Rng;
/**
* The current frame that is being recorded.
*/
currentFrame: ExecutionFrame;
/**
* Clear the recorded trace
*/
clear: () => void;
/**
* The best recorded traces.
*/
bestTraces: Trace[];
}
export declare const newTraceRecorder: (verbosityLevel: number, rng: Rng, tracesToRecord?: number) => TraceRecorder;