UNPKG

@informalsystems/quint

Version:

Core tool for the Quint specification language

111 lines 3.82 kB
"use strict"; /* ---------------------------------------------------------------------------------- * Copyright 2022 Informal Systems * Licensed under the Apache License, Version 2.0. * See LICENSE in the project root for license information. * --------------------------------------------------------------------------------- */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.flattenUnions = exports.simplify = void 0; /** * Simplification for effects, including a check on multiple updates of the same entity * * @author Gabriela Moreira * * @module */ const lodash_isequal_1 = __importDefault(require("lodash.isequal")); const util_1 = require("../util"); /** * Simplifies a concrete effect by: * 1. Removing repeated entities (except for updates) * 2. Flattening nested unions * * @param e the concrete effect to be simplified * * @returns the simplified effect */ function simplifyConcreteEffect(e) { const components = e.components.map(c => { const flatEntity = flattenUnions(c.entity); const entity = c.kind === 'update' ? flatEntity : deduplicateEntity(flatEntity); return { kind: c.kind, entity }; }); return { kind: 'concrete', components }; } function simplify(e) { switch (e.kind) { case 'concrete': return simplifyConcreteEffect(e); case 'variable': return e; case 'arrow': { const params = e.params.map(simplify); const result = simplify(e.result); return { kind: 'arrow', params, result }; } } } exports.simplify = simplify; /** * Transforms entities of form [x, [y, z]] into [x, y, z] * * @param entity the entity to be transformed * * @returns the flattened form of union if a union. * Otherwise, the entity without change. */ function flattenUnions(entity) { if (entity.kind == 'union') { const unionEntities = []; const vars = []; const flattenEntities = entity.entities.map(v => flattenUnions(v)); flattenEntities.map(v => { switch (v.kind) { case 'variable': unionEntities.push(v); break; case 'concrete': vars.push(...v.stateVariables); break; case 'union': unionEntities.push(...v.entities); break; default: (0, util_1.unreachable)(v); } }); if (unionEntities.length > 0) { const entities = vars.length > 0 ? unionEntities.concat({ kind: 'concrete', stateVariables: vars }) : unionEntities; return entities.length > 1 ? { kind: 'union', entities: entities } : entities[0]; } else { return { kind: 'concrete', stateVariables: vars }; } } else { return entity; } } exports.flattenUnions = flattenUnions; function deduplicateEntity(entity) { switch (entity.kind) { case 'variable': return entity; case 'concrete': return { kind: 'concrete', stateVariables: Array.from(new Set(entity.stateVariables)) }; case 'union': { const nestedEntities = entity.entities.map(v => deduplicateEntity(v)); const unique = []; nestedEntities.forEach(entity => { if (!unique.some(v => (0, lodash_isequal_1.default)(v, entity))) { unique.push(entity); } }); return { kind: 'union', entities: unique }; } } } //# sourceMappingURL=simplification.js.map