UNPKG

@informalsystems/quint

Version:

Core tool for the Quint specification language

100 lines 5.19 kB
"use strict"; /* ---------------------------------------------------------------------------------- * Copyright 2023 Informal Systems * Licensed under the Apache License, Version 2.0. * See LICENSE in the project root for license information. * --------------------------------------------------------------------------------- */ Object.defineProperty(exports, "__esModule", { value: true }); exports.analyzeInc = exports.analyzeModules = void 0; const inferrer_1 = require("./types/inferrer"); const inferrer_2 = require("./effects/inferrer"); const modeChecker_1 = require("./effects/modeChecker"); const errorTree_1 = require("./errorTree"); const MultipleUpdatesChecker_1 = require("./effects/MultipleUpdatesChecker"); const typeApplicationResolution_1 = require("./types/typeApplicationResolution"); const NondetChecker_1 = require("./effects/NondetChecker"); /** * Analyzes multiple Quint modules and returns the analysis result. * * NOTE: This is modifies the `lookupTable` and the `quintModules`! * See XXX for the mutation sites. * * @param lookupTable - The lookup tables for the modules. * @param quintModules - The Quint modules to be analyzed. * @returns A tuple with a list of errors and the analysis output. */ function analyzeModules(lookupTable, quintModules) { const analyzer = new QuintAnalyzer(lookupTable); // XXX: the modules are mutated here. quintModules.forEach(m => (m.declarations = analyzer.analyzeDeclarations(m.declarations))); return analyzer.getResult(); } exports.analyzeModules = analyzeModules; /** * Analyzes declarations incrementally and returns the analysis result. * * NOTE: This is modifies the `lookupTable`! * See XXX for the mutation sites. * * @param analysisOutput - The previous analysis output to be used as a starting point. * @param lookupTable - The lookup tables for the modules. * @param declarations - The Quint declarations to be analyzed. * @returns A tuple with a list of errors and the analysis output. */ function analyzeInc(analysisOutput, lookupTable, declarations) { const analyzer = new QuintAnalyzer(lookupTable, analysisOutput); analyzer.analyzeDeclarations(declarations); return analyzer.getResult(); } exports.analyzeInc = analyzeInc; /** * Statically analyzes a Quint specification. * * This class is stateful and accumulates analyzed data for multiple modules. * Use it by calling the analyze method for each module and then calling the * getResult method to get the analysis result. * * @param lookupTable - The lookup tables for the modules. * @param previousOutput - The previous analysis output to be used as a starting point. */ class QuintAnalyzer { constructor(lookupTable, previousOutput) { this.errors = []; this.output = { types: new Map(), effects: new Map(), modes: new Map() }; // XXX: the lookUp table is mutated when TypeApplicationResolver is instantiated this.typeApplicationResolver = new typeApplicationResolution_1.TypeApplicationResolver(lookupTable); this.typeInferrer = new inferrer_1.TypeInferrer(lookupTable, previousOutput?.types); // FIXES: https://github.com/informalsystems/quint/issues/428 this.effectInferrer = new inferrer_2.EffectInferrer(lookupTable, new Map([...(previousOutput?.effects.entries() ?? [])])); this.multipleUpdatesChecker = new MultipleUpdatesChecker_1.MultipleUpdatesChecker(); this.modeChecker = new modeChecker_1.ModeChecker(previousOutput?.modes); this.nondetChecker = new NondetChecker_1.NondetChecker(lookupTable); } analyzeDeclarations(decls) { const [typAppErrMap, resolvedDecls] = this.typeApplicationResolver.resolveTypeApplications(decls); // XXX: the lookUp table is mutated during type inference const [typeErrMap, types] = this.typeInferrer.inferTypes(resolvedDecls); const [effectErrMap, effects] = this.effectInferrer.inferEffects(resolvedDecls); const updatesErrMap = this.multipleUpdatesChecker.checkEffects([...effects.values()]); const nondetErrors = this.nondetChecker.checkNondets(types, resolvedDecls); const [modeErrMap, modes] = this.modeChecker.checkModes(resolvedDecls, effects); const errorTrees = [...typeErrMap, ...effectErrMap, ...typAppErrMap]; // TODO: Type and effect checking should return QuintErrors instead of error trees this.errors.push(...errorTrees.map(([id, err]) => { return { code: 'QNT000', message: (0, errorTree_1.errorTreeToString)(err), reference: id, data: { trace: err } }; })); this.errors.push(...modeErrMap.values(), ...updatesErrMap.values(), ...nondetErrors); // We assume that ids are unique across modules, and map merging can be done // without collision checks this.output = { types: new Map([...this.output.types, ...types]), effects: new Map([...this.output.effects, ...effects]), modes: new Map([...this.output.modes, ...modes]), }; return resolvedDecls; } getResult() { return [this.errors, this.output]; } } //# sourceMappingURL=quintAnalyzer.js.map