UNPKG

@informalsystems/quint

Version:

Core tool for the Quint specification language

140 lines 7.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const mocha_1 = require("mocha"); const chai_1 = require("chai"); const parser_1 = require("../../src/types/parser"); const substitutions_1 = require("../../src/types/substitutions"); const printing_1 = require("../../src/types/printing"); const table = new Map(); (0, mocha_1.describe)('compose', () => { (0, mocha_1.it)('composes two substitutions', () => { const row = { kind: 'row', fields: [{ fieldName: 'f', fieldType: (0, parser_1.parseTypeOrThrow)('bool') }], other: { kind: 'empty' }, }; const s1 = [ { kind: 'type', name: 'a', value: (0, parser_1.parseTypeOrThrow)('int'), }, ]; const s2 = [ { kind: 'row', name: 'b', value: row, }, ]; const result = (0, substitutions_1.compose)(table, s1, s2); chai_1.assert.sameDeepMembers(result, [ { kind: 'type', name: 'a', value: (0, parser_1.parseTypeOrThrow)('int') }, { kind: 'row', name: 'b', value: row }, ]); }); (0, mocha_1.it)('unifies values of substitutions with same name', () => { const s1 = [{ kind: 'type', name: 'v1', value: (0, parser_1.parseTypeOrThrow)('int') }]; const s2 = [{ kind: 'type', name: 'v1', value: { kind: 'var', name: 'q' } }]; const result = (0, substitutions_1.compose)(table, s1, s2); chai_1.assert.sameDeepMembers(result, s1.concat([{ kind: 'type', name: 'q', value: (0, parser_1.parseTypeOrThrow)('int') }])); }); }); (0, mocha_1.describe)('applySubstitution', () => { (0, mocha_1.it)('substitutes variables in arrow type', () => { const s = [ { kind: 'type', name: 'a', value: { kind: 'int', id: 1n } }, { kind: 'type', name: 'b', value: { kind: 'bool', id: 2n } }, ]; const t = (0, parser_1.parseTypeOrThrow)('(a) => b'); const result = (0, substitutions_1.applySubstitution)(table, s, t); chai_1.assert.deepEqual(result, (0, parser_1.parseTypeOrThrow)('(int) => bool')); }); (0, mocha_1.it)('substitutes variables in function type', () => { const s = [ { kind: 'type', name: 'a', value: { kind: 'int', id: 1n } }, { kind: 'type', name: 'b', value: { kind: 'bool', id: 2n } }, ]; const t = (0, parser_1.parseTypeOrThrow)('a -> b'); const result = (0, substitutions_1.applySubstitution)(table, s, t); chai_1.assert.deepEqual(result, (0, parser_1.parseTypeOrThrow)('int -> bool')); }); (0, mocha_1.it)('substitutes variables in lists, sets and tuples types', () => { const s = [ { kind: 'type', name: 'a', value: { kind: 'int', id: 1n } }, { kind: 'type', name: 'b', value: { kind: 'bool', id: 3n } }, { kind: 'type', name: 'c', value: { kind: 'str', id: 5n } }, ]; const t = (0, parser_1.parseTypeOrThrow)('(List[a], Set[b], c)'); const result = (0, substitutions_1.applySubstitution)(table, s, t); chai_1.assert.deepEqual(result, (0, parser_1.parseTypeOrThrow)('(List[int], Set[bool], str)')); }); (0, mocha_1.it)('substitutes variables in record type', () => { const s = [ { kind: 'type', name: 'a', value: { kind: 'int', id: 1n } }, { kind: 'type', name: 'b', value: { kind: 'bool', id: 2n } }, ]; const t = (0, parser_1.parseTypeOrThrow)('{ a: a, b: b }'); const result = (0, substitutions_1.applySubstitution)(table, s, t); chai_1.assert.deepEqual(result, (0, parser_1.parseTypeOrThrow)('{ a: int, b: bool }')); }); (0, mocha_1.it)('substitutes variables in record type with row variable', () => { const s = [ { kind: 'type', name: 'a', value: { kind: 'int', id: 1n } }, { kind: 'type', name: 'b', value: { kind: 'bool', id: 2n } }, { kind: 'row', name: 'r', value: { kind: 'empty' } }, ]; const t = (0, parser_1.parseTypeOrThrow)('{ a: a, b: b | r }'); const result = (0, substitutions_1.applySubstitution)(table, s, t); chai_1.assert.deepEqual(result, (0, parser_1.parseTypeOrThrow)('{ a: int, b: bool }')); }); (0, mocha_1.it)('substitutes with transitivity', () => { const s = [ { kind: 'type', name: 'a', value: { kind: 'var', id: 1n, name: 'b' } }, { kind: 'type', name: 'b', value: { kind: 'bool', id: 2n } }, ]; const t = (0, parser_1.parseTypeOrThrow)('a'); const result = (0, substitutions_1.applySubstitution)(table, s, t); chai_1.assert.deepEqual(result, { kind: 'bool', id: 2n }); }); }); (0, mocha_1.describe)('applySubstitutionToConstraint', () => { const s = [ { kind: 'type', name: 'a', value: { kind: 'int', id: 1n } }, { kind: 'type', name: 'b', value: { kind: 'bool', id: 1n } }, ]; (0, mocha_1.it)('applies substitution to types in equality constraint', () => { const t1 = (0, parser_1.parseTypeOrThrow)('a'); const t2 = (0, parser_1.parseTypeOrThrow)('b'); const result = (0, substitutions_1.applySubstitutionToConstraint)(table, s, { kind: 'eq', types: [t1, t2], sourceId: 1n }); const expectedResult = { kind: 'eq', types: [(0, parser_1.parseTypeOrThrow)('int'), (0, parser_1.parseTypeOrThrow)('bool')], sourceId: 1n, }; chai_1.assert.deepEqual(result, expectedResult, `expected ${(0, printing_1.constraintToString)(expectedResult)}, got ${(0, printing_1.constraintToString)(result)}`); }); (0, mocha_1.it)('does nothing to empty constraint', () => { const result = (0, substitutions_1.applySubstitutionToConstraint)(table, s, { kind: 'empty' }); const expectedResult = { kind: 'empty' }; chai_1.assert.deepEqual(result, expectedResult, `expected ${(0, printing_1.constraintToString)(expectedResult)}, got ${(0, printing_1.constraintToString)(result)}`); }); (0, mocha_1.it)('applies substitution recursively to constraints in conjunction', () => { const c1 = { kind: 'eq', types: [(0, parser_1.parseTypeOrThrow)('a'), (0, parser_1.parseTypeOrThrow)('b')], sourceId: 1n }; const c2 = { kind: 'eq', types: [(0, parser_1.parseTypeOrThrow)('b'), (0, parser_1.parseTypeOrThrow)('b')], sourceId: 1n }; const result = (0, substitutions_1.applySubstitutionToConstraint)(table, s, { kind: 'conjunction', constraints: [c1, c2], sourceId: 1n }); const expected1 = { kind: 'eq', types: [(0, parser_1.parseTypeOrThrow)('int'), (0, parser_1.parseTypeOrThrow)('bool')], sourceId: 1n, }; const expected2 = { kind: 'eq', types: [(0, parser_1.parseTypeOrThrow)('bool'), (0, parser_1.parseTypeOrThrow)('bool')], sourceId: 1n, }; const expectedResult = { kind: 'conjunction', constraints: [expected1, expected2], sourceId: 1n }; chai_1.assert.deepEqual(result, expectedResult, `expected ${(0, printing_1.constraintToString)(expectedResult)}, got ${(0, printing_1.constraintToString)(result)}`); }); }); //# sourceMappingURL=substitutions.test.js.map