@informalsystems/quint
Version:
Core tool for the Quint specification language
140 lines • 7.4 kB
JavaScript
"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