"use strict";
// ---------------------------------------------------------------------------
// Constant Propagation Lattice
//
// Three-element lattice: Top → Constant(value) → Bottom
// Used by the whole-program data flow analyzer to track variable values.
// ---------------------------------------------------------------------------
Object.defineProperty(exports, "__esModule", { value: true });
exports.top = top;
exports.constant = constant;
exports.bottom = bottom;
exports.safeBottom = safeBottom;
exports.propagateBottom = propagateBottom;
exports.meet = meet;
exports.isTop = isTop;
exports.isConstant = isConstant;
exports.isBottom = isBottom;
// ---------------------------------------------------------------------------
// Factory functions
// ---------------------------------------------------------------------------
const TOP_SINGLETON = { kind: 'top' };
function top() {
    return TOP_SINGLETON;
}
function constant(value) {
    return { kind: 'constant', value };
}
function bottom(reason, sourceNode, rootCause) {
    return { kind: 'bottom', reason, sourceNode, rootCause };
}
function safeBottom(reason, sourceNode, rootCause) {
    return { kind: 'bottom', reason, sourceNode, rootCause, isSafe: true };
}
/**
 * Propagate a Bottom through a dependency chain.
 * The new Bottom inherits the root cause from the original.
 */
function propagateBottom(reason, source, sourceNode) {
    return {
        kind: 'bottom',
        reason,
        sourceNode,
        rootCause: source.rootCause ?? source,
        isSafe: source.isSafe,
    };
}
// ---------------------------------------------------------------------------
// Meet operation
// ---------------------------------------------------------------------------
/**
 * The meet (⊓) combines two lattice values:
 *   ⊤ ⊓ x = x
 *   x ⊓ ⊤ = x
 *   ⊥ ⊓ x = ⊥
 *   x ⊓ ⊥ = ⊥
 *   Constant(a) ⊓ Constant(b) = Constant(a) if a === b, else ⊥
 */
function meet(a, b) {
    if (a.kind === 'top')
        return b;
    if (b.kind === 'top')
        return a;
    if (a.kind === 'bottom')
        return a;
    if (b.kind === 'bottom')
        return b;
    // Both are constants
    if (a.value === b.value)
        return a;
    return bottom('Value differs across paths');
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function isTop(v) {
    return v.kind === 'top';
}
function isConstant(v) {
    return v.kind === 'constant';
}
function isBottom(v) {
    return v.kind === 'bottom';
}
//# sourceMappingURL=lattice.js.map