UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

100 lines 3.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PosIntervalDomain = exports.PosIntervalTop = void 0; const interval_domain_1 = require("./interval-domain"); const lattice_1 = require("./lattice"); /** The Top element of the positive interval domain as interval [0, +∞] */ exports.PosIntervalTop = [0, +Infinity]; /** * The positive interval abstract domain as positive intervals with possibly zero lower bounds and infinite upper bounds representing possible numeric values. * The Bottom element is defined as {@link Bottom} symbol and the Top element is defined as the interval [0, +∞]. * @template Value - Type of the constraint in the abstract domain (Top, Bottom, or an actual value) */ class PosIntervalDomain extends interval_domain_1.IntervalDomain { constructor(value) { if (Array.isArray(value) && value[0] < 0) { super(lattice_1.Bottom); } else { super(value); } } create(value) { return new PosIntervalDomain(value); } static top() { return new PosIntervalDomain(exports.PosIntervalTop); } static bottom() { return new PosIntervalDomain(lattice_1.Bottom); } static abstract(concrete) { if (concrete === lattice_1.Top) { return PosIntervalDomain.top(); } else if (concrete.size === 0 || concrete.values().some(value => isNaN(value) || value < 0)) { return PosIntervalDomain.bottom(); } return new PosIntervalDomain([Math.min(...concrete), Math.max(...concrete)]); } top() { return PosIntervalDomain.top(); } bottom() { return PosIntervalDomain.bottom(); } widen(other) { if (this.value === lattice_1.Bottom) { return this.create(other.value); } else if (other.value === lattice_1.Bottom) { return this.create(this.value); } else { return this.create([ this.value[0] <= other.value[0] ? this.value[0] : 0, this.value[1] >= other.value[1] ? this.value[1] : +Infinity ]); } } narrow(other) { if (this.value === lattice_1.Bottom || other.value === lattice_1.Bottom) { return this.bottom(); } else if (Math.max(this.value[0], other.value[0]) > Math.min(this.value[1], other.value[1])) { return this.bottom(); } return this.create([ this.value[0] === 0 ? other.value[0] : this.value[0], this.value[1] === +Infinity ? other.value[1] : this.value[1] ]); } abstract(concrete) { return PosIntervalDomain.abstract(concrete); } subtract(other) { const otherValue = other instanceof PosIntervalDomain ? other.value : other; if (this.value === lattice_1.Bottom || otherValue === lattice_1.Bottom) { return this.bottom(); } else { return this.create([Math.max(this.value[0] - otherValue[0], 0), Math.max(this.value[1] - otherValue[1], 0)]); } } /** * Extends the lower bound of the current abstract value down to 0. */ widenDown() { if (this.value === lattice_1.Bottom) { return this.bottom(); } else { return this.create([0, this.value[1]]); } } isTop() { return this.value !== lattice_1.Bottom && this.value[0] === 0 && this.value[1] === +Infinity; } } exports.PosIntervalDomain = PosIntervalDomain; //# sourceMappingURL=positive-interval-domain.js.map