@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
115 lines • 3.65 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SingletonDomain = void 0;
const abstract_domain_1 = require("./abstract-domain");
const lattice_1 = require("./lattice");
/**
* The singleton abstract domain as single possible value.
* The Bottom element is defined as {@link Bottom} symbol and the Top element is defined as {@link Top} symbol.
* @template T - Type of the value in the abstract domain
* @template Value - Type of the constraint in the abstract domain (Top, Bottom, or an actual value)
*/
class SingletonDomain {
_value;
constructor(value) {
this._value = value;
}
get value() {
return this._value;
}
static top() {
return new SingletonDomain(lattice_1.Top);
}
static bottom() {
return new SingletonDomain(lattice_1.Bottom);
}
static abstract(concrete) {
if (concrete === lattice_1.Top || concrete.size > 1) {
return SingletonDomain.top();
}
else if (concrete.size === 0) {
return SingletonDomain.bottom();
}
return new SingletonDomain([...concrete][0]);
}
top() {
return SingletonDomain.top();
}
bottom() {
return SingletonDomain.bottom();
}
equals(other) {
return this.value === other.value;
}
leq(other) {
return this.value === lattice_1.Bottom || other.value === lattice_1.Top || (this.isValue() && other.isValue() && this.value <= other.value);
}
join(...values) {
const result = new SingletonDomain(this.value);
for (const other of values) {
if (result.value === lattice_1.Bottom) {
result._value = other.value;
}
else if (other.value === lattice_1.Bottom) {
result._value = result.value;
}
else if (result.value !== other.value) {
result._value = lattice_1.Top;
}
}
return result;
}
meet(...values) {
const result = new SingletonDomain(this.value);
for (const other of values) {
if (result.value === lattice_1.Top) {
result._value = other.value;
}
else if (other.value === lattice_1.Top) {
result._value = result.value;
}
else if (result.value !== other.value) {
result._value = lattice_1.Bottom;
}
}
return result;
}
widen(other) {
return this.join(other); // Using join for widening as the lattice is finite
}
narrow(other) {
return this.meet(other); // Using meet for narrowing as the lattice is finite
}
concretize() {
if (this.value === lattice_1.Top) {
return lattice_1.Top;
}
else if (this.value === lattice_1.Bottom) {
return new Set();
}
return new Set([this.value]);
}
abstract(concrete) {
return SingletonDomain.abstract(concrete);
}
toString() {
if (this.value === lattice_1.Top) {
return '⊤';
}
else if (this.value === lattice_1.Bottom) {
return '⊥';
}
return (0, abstract_domain_1.domainElementToString)(this.value);
}
isTop() {
return this.value === lattice_1.Top;
}
isBottom() {
return this.value === lattice_1.Bottom;
}
isValue() {
return this.value !== lattice_1.Top && this.value !== lattice_1.Bottom;
}
}
exports.SingletonDomain = SingletonDomain;
//# sourceMappingURL=singleton-domain.js.map