@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
100 lines • 3.63 kB
JavaScript
"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