@informalsystems/quint
Version:
Core tool for the Quint specification language
121 lines (120 loc) • 5.3 kB
TypeScript
/**
* A builder to build arrow functions used to evaluate Quint expressions.
*
* Caching and var storage are heavily based on the original `compilerImpl.ts` file written by Igor Konnov.
* The performance of evaluation relies on a lot of memoization done mainly with closures in this file.
* We define registers and cached value data structures that work as pointers, to avoid the most lookups and
* memory usage as possible. This adds a lot of complexity to the code, but it is necessary to achieve feasible
* performance, as the functions built here will be called thousands of times by the simulator.
*
* @author Igor Konnov, Gabriela Moreira
*
* @module
*/
import { Either } from '@sweet-monads/either';
import { QuintError } from '../../quintError';
import { RuntimeValue } from './runtimeValue';
import { CachedValue, Context, Register } from './Context';
import { QuintEx, QuintVar } from '../../ir/quintIr';
import { LookupDefinition, LookupTable } from '../../names/base';
import { NamedRegister, VarStorage } from './VarStorage';
import { List } from 'immutable';
/**
* The type returned by the builder in its methods, which can be called to get the
* evaluation result under a given context.
*/
export type EvalFunction = (ctx: Context) => Either<QuintError, RuntimeValue>;
/**
* A builder to build arrow functions used to evaluate Quint expressions.
* It can be understood as a Quint compiler that compiles Quint expressions into
* typescript arrow functions. It is called a builder instead of compiler because
* the compiler term is overloaded.
*/
export declare class Builder {
table: LookupTable;
paramRegistry: Map<bigint, Register>;
constRegistry: Map<bigint, Register>;
scopedCachedValues: Map<bigint, CachedValue>;
initialNondetPicks: Map<string, RuntimeValue | undefined>;
memo: Map<bigint, EvalFunction>;
memoByInstance: Map<bigint, Map<bigint, EvalFunction>>;
namespaces: List<string>;
varStorage: VarStorage;
/**
* Constructs a new Builder instance.
*
* @param table - The lookup table containing definitions.
* @param storeMetadata - A flag indicating whether to store metadata (`actionTaken` and `nondetPicks`).
*/
constructor(table: LookupTable, storeMetadata: boolean);
/**
* Adds a variable to the var storage if it is not there yet.
*
* @param id
* @param name
*/
discoverVar(id: bigint, name: string): void;
/**
* Gets the register for a variable by its id and the namespaces in scope (tracked by this builder).
*
* @param def - The variable to get the register for.
*
* @returns the register for the variable
*/
getVar(def: QuintVar): NamedRegister;
/**
* Gets the register for the next state of a variable by its id and the namespaces in scope (tracked by this builder).
*
* @param id - The identifier of the variable.
*
* @returns the register for the next state of the variable
*/
getNextVar(id: bigint): NamedRegister;
/**
* Gets the register for a constant by its id and the instances in scope (tracked by this builder).
*
* @param id - The identifier of the constant.
* @param name - The constant name to be used in error messages.
*
* @returns the register for the constant
*/
registerForConst(id: bigint, name: string): Register;
}
/**
* Builds an evaluation function for a given Quint expression.
*
* This function first checks if the expression has already been memoized. If it has,
* it returns the memoized evaluation function. If not, it builds the core evaluation
* function for the expression and wraps it to handle errors and memoization.
*
* @param builder - The Builder instance used to construct the evaluation function.
* @param expr - The Quint expression to evaluate.
*
* @returns An evaluation function that takes a context and returns either a QuintError or a RuntimeValue.
*/
export declare function buildExpr(builder: Builder, expr: QuintEx): EvalFunction;
/**
* Builds an evaluation function for a given definition.
*
* This function first checks if the definition has already been memoized. If it has,
* it returns the memoized evaluation function. If the definition is imported from an instance,
* it builds the evaluation function under the context of the instance. Otherwise, it builds the
* core evaluation function for the definition and wraps it to handle errors and memoization.
*
* @param builder - The Builder instance used to construct the evaluation function.
* @param def - The LookupDefinition to evaluate.
*
* @returns An evaluation function that takes a context and returns either a QuintError or a RuntimeValue.
*/
export declare function buildDef(builder: Builder, def: LookupDefinition): EvalFunction;
/**
* Constructs a fully qualified name by combining the given name with the namespaces.
*
* The namespaces are reversed and joined with the name using the "::" delimiter.
*
* @param name - The name to be qualified.
* @param namespaces - A list of namespaces to be included in the fully qualified name.
*
* @returns The fully qualified name as a string.
*/
export declare function nameWithNamespaces(name: string, namespaces: List<string>): string;