UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

92 lines 3.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AbstractDomain = exports.DEFAULT_INFERENCE_LIMIT = void 0; exports.domainElementToString = domainElementToString; exports.isAbstractDomain = isAbstractDomain; const assert_1 = require("../../util/assert"); const lattice_1 = require("./lattice"); /** * The default limit of inferred constraints in {@link AbstractDomain|AbstractDomains}. */ exports.DEFAULT_INFERENCE_LIMIT = 50; /** * An abstract domain as complete lattice with a widening operator, narrowing operator, concretization function, and abstraction function. * All operations of value abstract domains should not modify the domain in-place but return new values using {@link create}. * @template Concrete - Type of an concrete element of the concrete domain for the abstract domain * @template Abstract - Type of an abstract element of the abstract domain representing possible elements (excludes `Top` and `Bot`) * @template Top - Type of the Top element of the abstract domain representing all possible elements * @template Bot - Type of the Bottom element of the abstract domain representing no possible elements * @template Value - Type of the abstract elements of the abstract domain (defaults to `Abstract` or `Top` or `Bot`) */ class AbstractDomain { _value; constructor(value) { this._value = value; } get value() { return this._value; } /** * Joins the current abstract value with multiple other abstract values. */ joinAll(values) { let result = this.create(this.value); for (const other of values) { result = result.join(other); } return result; } /** * Meets the current abstract value with multiple other abstract values. */ meetAll(values) { let result = this.create(this.value); for (const other of values) { result = result.meet(other); } return result; } /** * Joins an array of abstract values by joining the first abstract value with the other values in the array. * The provided array of abstract values must not be empty or a default value must be provided! */ static joinAll(values, defaultValue) { (0, assert_1.guard)(values.length > 0 || defaultValue !== undefined, 'Abstract values to join cannot be empty'); return values[0]?.joinAll(values.slice(1)) ?? defaultValue; } /** * Meets an array of abstract values by meeting the first abstract value with the other values in the array. * The provided array of abstract values must not be empty or a default value must be provided! */ static meetAll(values, defaultValue) { (0, assert_1.guard)(values.length > 0 || defaultValue !== undefined, 'Abstract values to meet cannot be empty'); return values[0]?.meetAll(values.slice(1)) ?? defaultValue; } } exports.AbstractDomain = AbstractDomain; /** * Converts an element of an abstract domain into a string. */ function domainElementToString(value) { if (typeof value === 'object' && value !== null && value.toString !== Object.prototype.toString) { // eslint-disable-next-line @typescript-eslint/no-base-to-string return value.toString(); } else if (value === lattice_1.Top) { return lattice_1.TopSymbol; } else if (value === lattice_1.Bottom) { return lattice_1.BottomSymbol; } return JSON.stringify(value); } /** * Checks whether a value is an abstract domain. */ function isAbstractDomain(value) { if (typeof value !== 'object' || value === null) { return false; } return ['value', 'top', 'bottom', 'leq', 'join', 'meet', 'widen', 'narrow', 'concretize', 'abstract'].every(property => property in value); } //# sourceMappingURL=abstract-domain.js.map