Skip to documentation
SLOP

tiny.pluck.bdd.Manager

Reference tiny.pluck bdd Manager

Defined in bdd.

API (64)

Actions

Public operations.

Fields and members

Public fields and members.

No direct callersNo direct callsbddManager
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/pluck/src/bdd.zig:422

zig
pub const Manager = struct {    const TABLE_MAX_LOAD_PERCENTAGE = 80;    allocator: Allocator,    nodes: std.ArrayListUnmanaged(Node),    unique_table: std.HashMapUnmanaged(Node, NodeIndex, NodeHashContext, TABLE_MAX_LOAD_PERCENTAGE),    unique_table_grow_at: usize,    ite_cache: std.HashMapUnmanaged(IteKey, Bdd, IteKeyHashContext, TABLE_MAX_LOAD_PERCENTAGE),    ite_cache_grow_at: usize,    condition_cache: std.AutoHashMapUnmanaged(ConditionKey, Bdd),    var_order: std.ArrayListUnmanaged(u32),    min_vars: std.ArrayListUnmanaged(VarLabel),    max_vars: std.ArrayListUnmanaged(VarLabel),    num_recursive_calls: u64,    ite_cache_hits: u64,    ite_cache_misses: u64,    unique_table_grows: u64,    ite_cache_grows: u64,    limits: LimitConfig,    const INITIAL_MANAGER_CAPACITY = 4096;    const INITIAL_CONDITION_CACHE_CAPACITY = 256;    fn tableLoadThreshold(capacity: usize) usize {        return (capacity * TABLE_MAX_LOAD_PERCENTAGE) / 100;    }    pub fn init(allocator: Allocator) !Manager {        var nodes = std.ArrayListUnmanaged(Node).empty;        errdefer nodes.deinit(allocator);        var min_vars = std.ArrayListUnmanaged(VarLabel).empty;        errdefer min_vars.deinit(allocator);        var max_vars = std.ArrayListUnmanaged(VarLabel).empty;        errdefer max_vars.deinit(allocator);        try nodes.ensureTotalCapacity(allocator, INITIAL_MANAGER_CAPACITY);        try min_vars.ensureTotalCapacity(allocator, INITIAL_MANAGER_CAPACITY);        try max_vars.ensureTotalCapacity(allocator, INITIAL_MANAGER_CAPACITY);        try nodes.append(allocator, Node.init(NO_VAR, Bdd.TRUE, Bdd.TRUE));        try min_vars.append(allocator, NO_VAR);        try max_vars.append(allocator, NO_VAR);        var unique_table = std.HashMapUnmanaged(Node, NodeIndex, NodeHashContext, TABLE_MAX_LOAD_PERCENTAGE){};        errdefer unique_table.deinit(allocator);        try unique_table.ensureTotalCapacity(allocator, INITIAL_MANAGER_CAPACITY);        var ite_cache = std.HashMapUnmanaged(IteKey, Bdd, IteKeyHashContext, TABLE_MAX_LOAD_PERCENTAGE){};        errdefer ite_cache.deinit(allocator);        try ite_cache.ensureTotalCapacity(allocator, INITIAL_MANAGER_CAPACITY);        var condition_cache = std.AutoHashMapUnmanaged(ConditionKey, Bdd){};        errdefer condition_cache.deinit(allocator);        try condition_cache.ensureTotalCapacity(allocator, INITIAL_CONDITION_CACHE_CAPACITY);        return Manager{            .allocator = allocator,            .nodes = nodes,            .unique_table = unique_table,            .unique_table_grow_at = tableLoadThreshold(unique_table.capacity()),            .ite_cache = ite_cache,            .ite_cache_grow_at = tableLoadThreshold(ite_cache.capacity()),            .condition_cache = condition_cache,            .var_order = std.ArrayListUnmanaged(u32).empty,            .min_vars = min_vars,            .max_vars = max_vars,            .num_recursive_calls = 0,            .ite_cache_hits = 0,            .ite_cache_misses = 0,            .unique_table_grows = 0,            .ite_cache_grows = 0,            .limits = LimitConfig.init(),        };    }    pub fn deinit(self: *Manager) void {        self.nodes.deinit(self.allocator);        self.unique_table.deinit(self.allocator);        self.ite_cache.deinit(self.allocator);        self.condition_cache.deinit(self.allocator);        self.var_order.deinit(self.allocator);        self.min_vars.deinit(self.allocator);        self.max_vars.deinit(self.allocator);    }    pub fn numVars(self: *const Manager) usize {        return self.var_order.items.len;    }    pub fn newVar(self: *Manager, polarity: bool) Allocator.Error!Bdd {        const label: VarLabel = @intCast(self.var_order.items.len);        const node = Node.init(label, Bdd.FALSE, Bdd.TRUE);        if (!try self.prepareVariableInsert(node)) return Bdd.FALSE;        self.var_order.appendAssumeCapacity(label);        const bdd = self.insertCanonicalAssumeCapacity(node);        return if (polarity) bdd else bdd.neg();    }    pub fn newVarAtPosition(self: *Manager, position: u32, polarity: bool) Allocator.Error!Bdd {        const label: VarLabel = @intCast(self.var_order.items.len);        const node = Node.init(label, Bdd.FALSE, Bdd.TRUE);        if (!try self.prepareVariableInsert(node)) return Bdd.FALSE;        for (self.var_order.items) |*pos| {            if (pos.* >= position) {                pos.* += 1;            }        }        self.var_order.appendAssumeCapacity(position);        const bdd = self.insertCanonicalAssumeCapacity(node);        return if (polarity) bdd else bdd.neg();    }    fn prepareVariableInsert(self: *Manager, node: Node) Allocator.Error!bool {        std.debug.assert(self.unique_table.getContext(node, NodeHashContext{}) == null);        if (self.limits.checkNodeGrowth(self.nodes.items.len)) return false;        self.ensureCanonicalInsertCapacity() catch |err| {            if (self.limits.boundedAllocationFailed()) return false;            return err;        };        self.var_order.ensureUnusedCapacity(self.allocator, 1) catch |err| {            if (self.limits.boundedAllocationFailed()) return false;            return err;        };        return true;    }    fn getOrInsert(self: *Manager, node: Node) Allocator.Error!Bdd {        if (node.low.toRaw() == node.high.toRaw()) {            return node.low;        }        if (node.high.complement) {            const canonical = Node.init(                node.var_label,                node.low.neg(),                node.high.neg(),            );            return (try self.insertCanonical(canonical)).neg();        } else {            return self.insertCanonical(node);        }    }    fn insertCanonical(self: *Manager, node: Node) Allocator.Error!Bdd {        if (self.unique_table.getContext(node, NodeHashContext{})) |index| {            return Bdd{ .index = @intCast(index), .complement = false };        }        if (self.limits.checkNodeGrowth(self.nodes.items.len)) return Bdd.FALSE;        self.ensureCanonicalInsertCapacity() catch |err| {            if (self.limits.boundedAllocationFailed()) return Bdd.FALSE;            return err;        };        return self.insertCanonicalAssumeCapacity(node);    }    fn insertCanonicalAssumeCapacity(self: *Manager, node: Node) Bdd {        const entry = self.unique_table.getOrPutAssumeCapacityContext(node, NodeHashContext{});        std.debug.assert(!entry.found_existing);        const idx: u31 = @intCast(self.nodes.items.len);        self.nodes.appendAssumeCapacity(node);        const low_min = self.min_vars.items[node.low.index];        const low_max = self.max_vars.items[node.low.index];        const high_min = self.min_vars.items[node.high.index];        const high_max = self.max_vars.items[node.high.index];        var min_var = node.var_label;        if (low_min != NO_VAR and low_min < min_var) min_var = low_min;        if (high_min != NO_VAR and high_min < min_var) min_var = high_min;        var max_var = node.var_label;        if (low_max != NO_VAR and low_max > max_var) max_var = low_max;        if (high_max != NO_VAR and high_max > max_var) max_var = high_max;        self.min_vars.appendAssumeCapacity(min_var);        self.max_vars.appendAssumeCapacity(max_var);        entry.value_ptr.* = idx;        return Bdd{ .index = idx, .complement = false };    }    fn ensureCanonicalInsertCapacity(self: *Manager) Allocator.Error!void {        if (self.nodes.items.len >= self.nodes.capacity) {            const reserve = @max(self.nodes.capacity, INITIAL_MANAGER_CAPACITY);            const target = self.nodes.items.len + reserve;            try self.nodes.ensureTotalCapacity(self.allocator, target);            try self.min_vars.ensureTotalCapacity(self.allocator, target);            try self.max_vars.ensureTotalCapacity(self.allocator, target);        }        const count = self.unique_table.count();        if (count < self.unique_table_grow_at) return;        const capacity = self.unique_table.capacity();        const reserve = @max(capacity, INITIAL_MANAGER_CAPACITY);        try self.unique_table.ensureTotalCapacity(self.allocator, count + reserve);        self.unique_table_grows += 1;        self.unique_table_grow_at = tableLoadThreshold(self.unique_table.capacity());    }    pub inline fn getNode(self: *const Manager, bdd: Bdd) Node {        return self.nodes.items[bdd.index];    }    pub inline fn topVar(self: *const Manager, bdd: Bdd) VarLabel {        if (bdd.isConst()) return NO_VAR;        return self.getNode(bdd).var_label;    }    pub fn getMinVar(self: *const Manager, bdd: Bdd) VarLabel {        return self.min_vars.items[bdd.index];    }    pub fn getMaxVar(self: *const Manager, bdd: Bdd) VarLabel {        return self.max_vars.items[bdd.index];    }    pub fn low(self: *const Manager, bdd: Bdd) Bdd {        if (bdd.isConst()) return Bdd.FALSE;        const node = self.getNode(bdd);        return if (bdd.complement) node.low.neg() else node.low;    }    pub fn high(self: *const Manager, bdd: Bdd) Bdd {        if (bdd.isConst()) return Bdd.FALSE;        const node = self.getNode(bdd);        return if (bdd.complement) node.high.neg() else node.high;    }    inline fn lessThan(self: *const Manager, a: VarLabel, b: VarLabel) bool {        if (a == NO_VAR) return false;        if (b == NO_VAR) return true;        return self.var_order.items[a] < self.var_order.items[b];    }    inline fn firstEssential(self: *const Manager, f: Bdd, g: Bdd, h: Bdd) VarLabel {        const vf = self.topVar(f);        const vg = self.topVar(g);        const vh = self.topVar(h);        var result = vf;        if (self.lessThan(vg, result)) result = vg;        if (self.lessThan(vh, result)) result = vh;        return result;    }    inline fn conditionEssential(self: *const Manager, f: Bdd, lbl: VarLabel, value: bool) Bdd {        if (f.isConst()) return f;        const node = self.getNode(f);        if (node.var_label != lbl) return f;        const result = if (value) node.high else node.low;        return if (f.complement) result.neg() else result;    }    pub fn checkLimits(self: *Manager) bool {        if (self.limits.ite_limit_exceeded or self.limits.time_limit_exceeded) return true;        if (self.limits.checkIteLimit(self.num_recursive_calls)) {            return true;        }        if (self.num_recursive_calls % 1000 == 0) {            if (self.limits.checkTimeLimit()) {                return true;            }        }        return false;    }    pub fn iteLimitExceeded(self: *const Manager) bool {        return self.limits.ite_limit_exceeded;    }    pub fn timeLimitExceeded(self: *const Manager) bool {        return self.limits.time_limit_exceeded;    }    pub fn setTimeLimit(self: *Manager, limit_seconds: f64) void {        self.limits.time_limit = limit_seconds;        self.limits.time_limit_exceeded = false;    }    pub fn startTimeLimit(self: *Manager, limit_seconds: f64) void {        self.limits.startTimeLimit(limit_seconds);    }    pub fn stopTimeLimit(self: *Manager) void {        self.limits.stopTimeLimit();    }    pub fn resetLimitFlags(self: *Manager) void {        self.limits.time_limit_exceeded = false;        self.limits.ite_limit_exceeded = false;    }    pub fn startIteLimit(self: *Manager, limit: u64) void {        self.limits.startIteLimit(            limit,            self.num_recursive_calls,            self.nodes.items.len,            self.ite_cache.count(),        );    }    pub fn stopIteLimit(self: *Manager) void {        self.limits.stopIteLimit();    }    pub fn ite(self: *Manager, f: Bdd, g: Bdd, h: Bdd) Allocator.Error!Bdd {        self.num_recursive_calls += 1;        if (self.limits.ite_limit_exceeded or self.limits.time_limit_exceeded) {            return Bdd.FALSE;        }        if (self.num_recursive_calls % 1000 == 0) {            if (self.checkLimits()) return Bdd.FALSE;        }        const helper = LessThanHelper{ .manager = self };        const normalized = NormalizedIte.normalize(f, g, h, helper);        if (normalized.is_const) {            return normalized.const_result;        }        if (self.ite_cache.get(normalized.key)) |cached| {            self.ite_cache_hits += 1;            return if (normalized.complement_result) cached.neg() else cached;        }        self.ite_cache_misses += 1;        if (self.limits.reserveIteCacheGrowth(self.ite_cache.count())) return Bdd.FALSE;        defer self.limits.releaseIteCacheGrowth();        const top_var = self.firstEssential(f, g, h);        const fx_t = self.conditionEssential(f, top_var, true);        const gx_t = self.conditionEssential(g, top_var, true);        const hx_t = self.conditionEssential(h, top_var, true);        const fx_f = self.conditionEssential(f, top_var, false);        const gx_f = self.conditionEssential(g, top_var, false);        const hx_f = self.conditionEssential(h, top_var, false);        const t = try self.ite(fx_t, gx_t, hx_t);        if (self.limits.ite_limit_exceeded or self.limits.time_limit_exceeded) {            return Bdd.FALSE;        }        const e = try self.ite(fx_f, gx_f, hx_f);        if (self.limits.ite_limit_exceeded or self.limits.time_limit_exceeded) {            return Bdd.FALSE;        }        if (t.toRaw() == e.toRaw()) {            const cache_result = if (normalized.complement_result) t.neg() else t;            if (!try self.putIteCacheNoClobber(normalized.key, cache_result)) return Bdd.FALSE;            return t;        }        const result = try self.getOrInsert(Node.init(top_var, e, t));        if (self.limits.ite_limit_exceeded) return Bdd.FALSE;        const cache_result = if (normalized.complement_result) result.neg() else result;        if (!try self.putIteCacheNoClobber(normalized.key, cache_result)) return Bdd.FALSE;        return result;    }    fn putIteCacheNoClobber(self: *Manager, key: IteKey, value: Bdd) Allocator.Error!bool {        if (!try self.ensureReservedIteCacheCapacity()) return false;        self.ite_cache.putAssumeCapacityNoClobber(key, value);        return true;    }    fn ensureReservedIteCacheCapacity(self: *Manager) Allocator.Error!bool {        const reservations = @max(self.limits.ite_cache_reservations, 1);        std.debug.assert(reservations <= std.math.maxInt(u32));        const projected = self.ite_cache.count() +| reservations;        if (projected <= self.ite_cache_grow_at) return true;        const capacity = self.ite_cache.capacity();        const reserve = @max(capacity, INITIAL_MANAGER_CAPACITY);        const target = @max(projected, self.ite_cache.count() +| reserve);        const target_size = std.math.cast(u32, target) orelse {            if (self.limits.boundedAllocationFailed()) return false;            return error.OutOfMemory;        };        self.ite_cache.ensureTotalCapacity(self.allocator, target_size) catch |err| {            if (self.limits.boundedAllocationFailed()) return false;            return err;        };        self.ite_cache_grows += 1;        self.ite_cache_grow_at = tableLoadThreshold(self.ite_cache.capacity());        return true;    }    pub fn bddAnd(self: *Manager, a: Bdd, b: Bdd) Allocator.Error!Bdd {        if (a.isFalse() or b.isFalse()) return Bdd.FALSE;        if (a.isTrue()) return b;        if (b.isTrue()) return a;        if (a.toRaw() == b.toRaw()) return a;        if (a.neg().toRaw() == b.toRaw()) return Bdd.FALSE;        var left = a;        var right = b;        if (right.toRaw() < left.toRaw()) {            const tmp = left;            left = right;            right = tmp;        }        return self.ite(left, right, Bdd.FALSE);    }    pub fn bddOr(self: *Manager, a: Bdd, b: Bdd) Allocator.Error!Bdd {        if (a.isTrue() or b.isTrue()) return Bdd.TRUE;        if (a.isFalse()) return b;        if (b.isFalse()) return a;        if (a.toRaw() == b.toRaw()) return a;        if (a.neg().toRaw() == b.toRaw()) return Bdd.TRUE;        var left = a;        var right = b;        if (right.toRaw() < left.toRaw()) {            const tmp = left;            left = right;            right = tmp;        }        return self.ite(left, Bdd.TRUE, right);    }    pub fn bddNot(_: *Manager, a: Bdd) Bdd {        return a.neg();    }    pub fn bddXor(self: *Manager, a: Bdd, b: Bdd) Allocator.Error!Bdd {        if (a.isFalse()) return b;        if (b.isFalse()) return a;        if (a.isTrue()) return b.neg();        if (b.isTrue()) return a.neg();        if (a.toRaw() == b.toRaw()) return Bdd.FALSE;        if (a.neg().toRaw() == b.toRaw()) return Bdd.TRUE;        var left = a;        var right = b;        if (right.toRaw() < left.toRaw()) {            const tmp = left;            left = right;            right = tmp;        }        return self.ite(left, right.neg(), right);    }    pub fn bddIff(self: *Manager, a: Bdd, b: Bdd) Allocator.Error!Bdd {        if (a.isFalse()) return b.neg();        if (b.isFalse()) return a.neg();        if (a.isTrue()) return b;        if (b.isTrue()) return a;        if (a.toRaw() == b.toRaw()) return Bdd.TRUE;        if (a.neg().toRaw() == b.toRaw()) return Bdd.FALSE;        var left = a;        var right = b;        if (right.toRaw() < left.toRaw()) {            const tmp = left;            left = right;            right = tmp;        }        return self.ite(left, right, right.neg());    }    pub fn bddImplies(self: *Manager, a: Bdd, b: Bdd) Allocator.Error!Bdd {        if (a.isFalse() or b.isTrue()) return Bdd.TRUE;        if (a.isTrue()) return b;        if (b.isFalse()) return a.neg();        if (a.toRaw() == b.toRaw()) return Bdd.TRUE;        if (a.neg().toRaw() == b.toRaw()) return b;        return self.bddOr(a.neg(), b);    }    pub fn eq(self: *const Manager, a: Bdd, b: Bdd) bool {        _ = self;        return a.toRaw() == b.toRaw();    }    pub fn exists(self: *Manager, f: Bdd, variable: VarLabel) Allocator.Error!Bdd {        const f_true = try self.condition(f, variable, true);        const f_false = try self.condition(f, variable, false);        return self.bddOr(f_true, f_false);    }    pub fn condition(self: *Manager, f: Bdd, variable: VarLabel, value: bool) Allocator.Error!Bdd {        return self.conditionHelper(f, variable, value);    }    fn conditionHelper(self: *Manager, f: Bdd, variable: VarLabel, value: bool) Allocator.Error!Bdd {        if (f.isConst()) return f;        const node = self.getNode(f);        if (self.lessThan(variable, node.var_label)) {            return f;        }        if (node.var_label == variable) {            const result = if (value) node.high else node.low;            return if (f.complement) result.neg() else result;        }        const key = ConditionKey.init(f, variable, value);        if (self.condition_cache.get(key)) |cached| {            return cached;        }        const low_result = try self.conditionHelper(            if (f.complement) node.low.neg() else node.low,            variable,            value,        );        const high_result = try self.conditionHelper(            if (f.complement) node.high.neg() else node.high,            variable,            value,        );        if (low_result.toRaw() == high_result.toRaw()) {            if (!try self.putConditionCache(key, low_result)) return Bdd.FALSE;            return low_result;        }        const result = try self.getOrInsert(Node.init(node.var_label, low_result, high_result));        if (self.limits.ite_limit_exceeded) return Bdd.FALSE;        if (!try self.putConditionCache(key, result)) return Bdd.FALSE;        return result;    }    fn putConditionCache(self: *Manager, key: ConditionKey, value: Bdd) Allocator.Error!bool {        self.condition_cache.put(self.allocator, key, value) catch |err| {            if (self.limits.boundedAllocationFailed()) return false;            return err;        };        return true;    }    pub fn compose(self: *Manager, f: Bdd, variable: VarLabel, g: Bdd) Allocator.Error!Bdd {        if (f.isConst()) return f;        const node = self.getNode(f);        if (self.lessThan(variable, node.var_label)) {            return f;        }        const f_low = if (f.complement) node.low.neg() else node.low;        const f_high = if (f.complement) node.high.neg() else node.high;        if (node.var_label == variable) {            return self.ite(g, f_high, f_low);        }        const low_result = try self.compose(f_low, variable, g);        const high_result = try self.compose(f_high, variable, g);        if (low_result.toRaw() == high_result.toRaw()) {            return low_result;        }        return self.getOrInsert(Node.init(node.var_label, low_result, high_result));    }    pub fn sequentialCompose(        self: *Manager,        f: Bdd,        variables: []const VarLabel,        replacements: []const Bdd,    ) Allocator.Error!Bdd {        var result = f;        for (variables, replacements) |variable, replacement| {            result = try self.compose(result, variable, replacement);        }        return result;    }    pub fn isVar(self: *const Manager, bdd: Bdd) bool {        if (bdd.isConst()) return false;        const node = self.getNode(bdd);        const low_raw = if (bdd.complement) node.low.neg() else node.low;        const high_raw = if (bdd.complement) node.high.neg() else node.high;        return low_raw.isFalse() and high_raw.isTrue();    }    pub fn hasVariable(self: *const Manager, bdd: Bdd, variable: VarLabel) bool {        if (bdd.isConst()) return false;        const node = self.getNode(bdd);        if (node.var_label == variable) return true;        return self.hasVariable(node.low.toReg(), variable) or            self.hasVariable(node.high.toReg(), variable);    }    pub fn size(self: *const Manager, bdd: Bdd) usize {        if (bdd.isConst()) return 0;        var visited = std.AutoHashMap(u31, void).init(self.allocator);        defer visited.deinit();        return self.sizeHelper(bdd, &visited);    }    fn sizeHelper(self: *const Manager, bdd: Bdd, visited: *std.AutoHashMap(u31, void)) usize {        if (bdd.isConst()) return 0;        if (visited.contains(bdd.index)) return 0;        visited.put(bdd.index, {}) catch return 0;        const node = self.getNode(bdd);        return 1 + self.sizeHelper(node.low.toReg(), visited) +            self.sizeHelper(node.high.toReg(), visited);    }    pub fn numRecursiveCalls(self: *const Manager) u64 {        return self.num_recursive_calls;    }    pub fn resetStats(self: *Manager) void {        self.num_recursive_calls = 0;    }    pub fn clearCache(self: *Manager) void {        self.ite_cache.clearRetainingCapacity();        self.ite_cache_grow_at = tableLoadThreshold(self.ite_cache.capacity());        self.condition_cache.clearRetainingCapacity();    }    pub fn getVarPosition(self: *const Manager, var_label: VarLabel) u32 {        if (var_label >= self.var_order.items.len) return @intCast(self.var_order.items.len);        return self.var_order.items[var_label];    }    pub fn totalNodeCount(self: *const Manager) usize {        return if (self.nodes.items.len > 0) self.nodes.items.len - 1 else 0;    }    pub fn getVarAtPosition(self: *const Manager, position: u32) ?VarLabel {        for (self.var_order.items, 0..) |pos, label| {            if (pos == position) return @intCast(label);        }        return null;    }    pub fn nodesAtLevel(self: *const Manager, var_label: VarLabel) usize {        var count: usize = 0;        for (self.nodes.items[1..]) |node| {            if (node.var_label == var_label) count += 1;        }        return count;    }    pub fn swapAdjacentVars(self: *Manager, upper_pos: u32, allocator: Allocator) !i64 {        const lower_pos = upper_pos + 1;        const var_upper = self.getVarAtPosition(upper_pos) orelse return 0;        const var_lower = self.getVarAtPosition(lower_pos) orelse return 0;        const size_before = self.totalNodeCount();        var nodes_to_process: std.ArrayList(u31) = .empty;        defer nodes_to_process.deinit(allocator);        for (self.nodes.items[1..], 1..) |node, idx| {            if (node.var_label == var_upper) {                try nodes_to_process.append(allocator, @intCast(idx));            }        }        for (nodes_to_process.items) |idx| {            const node = self.nodes.items[idx];            const high_child = node.high;            const low_child = node.low;            var f11: Bdd = undefined;            var f10: Bdd = undefined;            var f01: Bdd = undefined;            var f00: Bdd = undefined;            if (!high_child.isConst() and self.getNode(high_child).var_label == var_lower) {                const high_node = self.getNode(high_child);                f11 = if (high_child.complement) high_node.high.neg() else high_node.high;                f10 = if (high_child.complement) high_node.low.neg() else high_node.low;            } else {                f11 = high_child;                f10 = high_child;            }            if (!low_child.isConst() and self.getNode(low_child).var_label == var_lower) {                const low_node = self.getNode(low_child);                f01 = if (low_child.complement) low_node.high.neg() else low_node.high;                f00 = if (low_child.complement) low_node.low.neg() else low_node.low;            } else {                f01 = low_child;                f00 = low_child;            }            const new_high = try self.getOrInsert(Node.init(var_upper, f01, f11));            const new_low = try self.getOrInsert(Node.init(var_upper, f00, f10));            _ = try self.getOrInsert(Node.init(var_lower, new_low, new_high));        }        self.var_order.items[var_upper] = lower_pos;        self.var_order.items[var_lower] = upper_pos;        self.clearCache();        const size_after = self.totalNodeCount();        return @as(i64, @intCast(size_after)) - @as(i64, @intCast(size_before));    }    pub fn localSift(self: *Manager, var_label: VarLabel, config: SiftConfig, allocator: Allocator) !SiftResult {        const original_pos = self.getVarPosition(var_label);        const num_vars = self.numVars();        if (num_vars <= 1) {            return SiftResult{                .original_pos = original_pos,                .final_pos = original_pos,                .size_delta = 0,                .aborted = false,            };        }        const original_size = self.totalNodeCount();        var best_pos = original_pos;        var best_size = original_size;        var current_pos = original_pos;        var aborted = false;        var moves_down: u32 = 0;        while (moves_down < config.max_distance and current_pos + 1 < num_vars) {            const delta = try self.swapAdjacentVars(current_pos, allocator);            current_pos += 1;            moves_down += 1;            const current_size = self.totalNodeCount();            if (current_size < best_size) {                best_size = current_size;                best_pos = current_pos;            }            if (original_size > 0) {                const blowup = @as(f64, @floatFromInt(current_size)) / @as(f64, @floatFromInt(original_size));                if (blowup > config.max_blowup) {                    aborted = true;                    break;                }            }            _ = delta;        }        while (current_pos > original_pos) {            _ = try self.swapAdjacentVars(current_pos - 1, allocator);            current_pos -= 1;        }        if (!aborted) {            var moves_up: u32 = 0;            while (moves_up < config.max_distance and current_pos > 0) {                _ = try self.swapAdjacentVars(current_pos - 1, allocator);                current_pos -= 1;                moves_up += 1;                const current_size = self.totalNodeCount();                if (current_size < best_size) {                    best_size = current_size;                    best_pos = current_pos;                }                if (original_size > 0) {                    const blowup = @as(f64, @floatFromInt(current_size)) / @as(f64, @floatFromInt(original_size));                    if (blowup > config.max_blowup) {                        aborted = true;                        break;                    }                }            }        }        while (current_pos < best_pos) {            _ = try self.swapAdjacentVars(current_pos, allocator);            current_pos += 1;        }        while (current_pos > best_pos) {            _ = try self.swapAdjacentVars(current_pos - 1, allocator);            current_pos -= 1;        }        const final_size = self.totalNodeCount();        return SiftResult{            .original_pos = original_pos,            .final_pos = best_pos,            .size_delta = @as(i64, @intCast(final_size)) - @as(i64, @intCast(original_size)),            .aborted = aborted,        };    }    pub fn globalSift(self: *Manager, config: SiftConfig, allocator: Allocator, max_passes: u32) !GlobalSiftResult {        const num_vars = self.numVars();        if (num_vars <= 1) {            const node_count = self.totalNodeCount();            return GlobalSiftResult{                .total_size_delta = 0,                .vars_sifted = 0,                .vars_improved = 0,                .original_size = node_count,                .final_size = node_count,            };        }        const original_size = self.totalNodeCount();        var total_delta: i64 = 0;        var vars_sifted: u32 = 0;        var vars_improved: u32 = 0;        var pass: u32 = 0;        while (pass < max_passes) : (pass += 1) {            var improved_this_pass = false;            var var_idx: VarLabel = 0;            while (var_idx < num_vars) : (var_idx += 1) {                const result = try self.localSift(var_idx, config, allocator);                vars_sifted += 1;                if (result.size_delta < 0) {                    vars_improved += 1;                    improved_this_pass = true;                }                total_delta += result.size_delta;            }            if (!improved_this_pass) break;        }        const final_size = self.totalNodeCount();        return GlobalSiftResult{            .total_size_delta = total_delta,            .vars_sifted = vars_sifted,            .vars_improved = vars_improved,            .original_size = original_size,            .final_size = final_size,        };    }    pub fn toString(self: *const Manager, bdd: Bdd, allocator: Allocator) ![]u8 {        var buffer = std.Io.Writer.Allocating.init(allocator);        errdefer buffer.deinit();        try self.toStringHelper(bdd, &buffer.writer);        return try buffer.toOwnedSlice();    }    fn toStringHelper(self: *const Manager, bdd: Bdd, writer: anytype) !void {        if (bdd.isTrue()) {            try writer.writeAll("T");        } else if (bdd.isFalse()) {            try writer.writeAll("F");        } else {            const node = self.getNode(bdd);            if (bdd.complement) {                try writer.writeAll("!");            }            try writer.print("({d}, ", .{node.var_label});            try self.toStringHelper(node.high, writer);            try writer.writeAll(", ");            try self.toStringHelper(node.low, writer);            try writer.writeAll(")");        }    }    pub fn toJson(self: *const Manager, bdd: Bdd, allocator: Allocator) ![]u8 {        return writeBddJson(allocator, bdd, self.nodes.items);    }    pub fn printStats(self: *const Manager, allocator: Allocator) ![]u8 {        var buffer = std.Io.Writer.Allocating.init(allocator);        errdefer buffer.deinit();        const writer = &buffer.writer;        try writer.print("BDD Manager Stats:\n", .{});        try writer.print("  Variables: {d}\n", .{self.var_order.items.len});        try writer.print("  Nodes: {d}\n", .{self.nodes.items.len});        try writer.print("  Unique table entries: {d}\n", .{self.unique_table.count()});        try writer.print("  ITE cache entries: {d}\n", .{self.ite_cache.count()});        try writer.print("  Condition cache entries: {d}\n", .{self.condition_cache.count()});        try writer.print("  Recursive calls: {d}\n", .{self.num_recursive_calls});        try writer.print("  ITE cache hits: {d}\n", .{self.ite_cache_hits});        try writer.print("  ITE cache misses: {d}\n", .{self.ite_cache_misses});        try writer.print("  Unique table grows: {d}\n", .{self.unique_table_grows});        try writer.print("  ITE cache grows: {d}\n", .{self.ite_cache_grows});        const total = self.ite_cache_hits + self.ite_cache_misses;        if (total > 0) {            const hit_ratio = @as(f64, @floatFromInt(self.ite_cache_hits)) / @as(f64, @floatFromInt(total)) * 100.0;            try writer.print("  ITE cache hit ratio: {d:.1}%\n", .{hit_ratio});        }        return try buffer.toOwnedSlice();    }};
Called byCallstest sourcelib.pluck.src.bddtest: CNF benchmark - 3-SAT clausetest sourcelib.pluck.src.bddtest: WmcContext - basic caching corr...test sourcelib.pluck.src.bddtest: WmcContext - invalidateForVars ...test sourcelib.pluck.src.bddtest: WmcContext - invalidateForVars ...test sourcelib.pluck.src.bddtest: WmcContext - manager change cle...+46 morebdd.Manageritebdd.ManagerbddAnd
Static calls · unresolved targets: 0 · external targets: 9.
Called byCallstest sourcelib.pluck.src.bddtest: binary boolean fast paths avoid...test sourcelib.pluck.src.bddtest: iff and xorprivate sourcelib.pluck.src.properties.bdd.TruthTablePropertypropertybdd.Manageritebdd.ManagerbddIff
Static calls · unresolved targets: 0 · external targets: 11.
Called byCallstest sourcelib.pluck.src.bddtest: binary boolean fast paths avoid...test sourcelib.pluck.src.bddtest: complement edge WMC correctness...test sourcelib.pluck.src.bddtest: implies operationtest sourcelib.pluck.src.bddtest: weighted sample - two variable ...test sourcelib.pluck.src.evaluatortest: flip produces path-condition-in...+2 morebdd.ManagerbddOrbdd.ManagerbddImplies
Static calls · unresolved targets: 0 · external targets: 7.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: complement edge WMC - double ne...test sourcelib.pluck.src.bddtest: complement edge WMC correctness...test sourcelib.pluck.src.bddtest: complemented edge preservationtest sourcelib.pluck.src.bddtest: condition cache with shared sub...test sourcelib.pluck.src.bddtest: de morgan's laws+5 morebdd.ManagerbddNot
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsbdd.ManagerbddImpliesbdd.Managerexiststest sourcelib.pluck.src.bddtest: CNF benchmark - 3-SAT clausetest sourcelib.pluck.src.bddtest: WmcContext - manager change cle...test sourcelib.pluck.src.bddtest: absorption law: a AND (a OR b) ...+23 morebdd.Manageritebdd.ManagerbddOr
Static calls · unresolved targets: 0 · external targets: 9.
Called byCallstest sourcelib.pluck.src.bddtest: binary boolean fast paths avoid...test sourcelib.pluck.src.bddtest: condition cache with shared sub...test sourcelib.pluck.src.bddtest: finite difference derivative va...test sourcelib.pluck.src.bddtest: iff and xortest sourcelib.pluck.src.bddtest: wmc scalar - larger formula+2 morebdd.Manageritebdd.ManagerbddXor
Static calls · unresolved targets: 0 · external targets: 11.
Called byCallsbdd.Manageritetest sourcelib.pluck.src.bddtest: manager ITE limit enforcementtest sourcelib.pluck.src.bddtest: manager ITE operation ceiling r...test sourcelib.pluck.src.bddtest: manager limits integrationbdd.LimitConfigcheckIteLimitbdd.LimitConfigcheckTimeLimitbdd.ManagercheckLimits
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsbdd.ManagerswapAdjacentVarsprivate sourcelib.pluck.src.bdd.ManagertableLoadThresholdbdd.ManagerclearCache
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsbdd.ManagersequentialComposetest sourcelib.pluck.src.bddtest: composetest sourcelib.pluck.src.bddtest: sequentialCompose behaviorbdd.ManagergetNodeprivate sourcelib.pluck.src.bdd.ManagergetOrInsertbdd.Manageriteprivate sourcelib.pluck.src.bdd.ManagerlessThanbdd.Nodeinitbdd.Managercompose
Static calls · unresolved targets: 0 · external targets: 5.
Called byCallsbdd.Managerexiststest sourcelib.pluck.src.bddtest: condition (restrict)test sourcelib.pluck.src.bddtest: condition cache with shared sub...test sourcelib.pluck.src.bddtest: newVarAtPosition preserves exis...test sourcelib.pluck.src.bddtest: three variable formula+7 moreprivate sourcelib.pluck.src.bdd.ManagerconditionHelperbdd.Managercondition
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.pluck.src.bddinitializeManagertest sourcelib.pluck.src.bddtest: CNF benchmark - 3-SAT clausetest sourcelib.pluck.src.bddtest: WmcContext - basic caching corr...test sourcelib.pluck.src.bddtest: WmcContext - cache invalidation...test sourcelib.pluck.src.bddtest: WmcContext - cache size and tri...+165 morebdd.Managerdeinit
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: absorption law: a AND (a OR b) ...test sourcelib.pluck.src.bddtest: absorption law: a OR (a AND b) ...test sourcelib.pluck.src.bddtest: and operationtest sourcelib.pluck.src.bddtest: complement edge WMC - double ne...test sourcelib.pluck.src.bddtest: complemented edge preservation+26 morebdd.Managereq
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstest sourcelib.pluck.src.bddtest: existential quantificationprivate sourcelib.pluck.src.properties.bdd.TruthTablePropertypropertybdd.ManagerbddOrbdd.Managerconditionbdd.Managerexists
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: min/max variable trackingbdd.ManagergetMaxVar
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: min/max variable trackingbdd.ManagergetMinVar
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsbdd.Managercomposeprivate sourcelib.pluck.src.bdd.ManagerconditionEssentialprivate sourcelib.pluck.src.bdd.ManagerconditionHelperbdd.ManagerhasVariablebdd.Managerhigh+7 morebdd.ManagergetNode
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsbdd.ManagerswapAdjacentVarstest sourcelib.pluck.src.bddtest: getVarPosition and getVarAtPosi...bdd.ManagergetVarAtPosition
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsbdd.ManagerlocalSifttest sourcelib.pluck.src.bddtest: getVarPosition and getVarAtPosi...test sourcelib.pluck.src.bddtest: localSift returns to best posit...test sourcelib.pluck.src.bddtest: swapAdjacentVars basicprivate sourcelib.pluck.src.weight.WeightDDbuildFromGuardListInner+3 morebdd.ManagergetVarPosition
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersbdd.ManagerlocalSiftbdd.ManagernumVarsbdd.ManagertotalNodeCountbdd.ManagerglobalSift
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.pluck.src.bddtest: has variablebdd.ManagergetNodebdd.ManagerhasVariable
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsNo direct callersbdd.ManagergetNodebdd.Managerhigh
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsprivate sourcelib.pluck.src.bddinitializeManagertest sourcelib.pluck.src.bddtest: CNF benchmark - 3-SAT clausetest sourcelib.pluck.src.bddtest: WmcContext - basic caching corr...test sourcelib.pluck.src.bddtest: WmcContext - cache invalidation...test sourcelib.pluck.src.bddtest: WmcContext - cache size and tri...+170 morebdd.LimitConfiginitprivate sourcelib.pluck.src.bdd.ManagertableLoadThresholdbdd.Nodeinitbdd.Managerinit
Static calls · unresolved targets: 3 · external targets: 14.
Called byCallstest sourcelib.pluck.src.bddtest: variable creationbdd.ManagergetNodebdd.ManagerisVar
Static calls · unresolved targets: 0 · external targets: 5.
Called byCallsbdd.ManagerbddAndbdd.ManagerbddIffbdd.ManagerbddOrbdd.ManagerbddXorbdd.Managercompose+2 morebdd.LimitConfigreleaseIteCacheGrowthbdd.LimitConfigreserveIteCacheGrowthbdd.ManagercheckLimitsprivate sourcelib.pluck.src.bdd.ManagerconditionEssentialprivate sourcelib.pluck.src.bdd.ManagerfirstEssential+4 morebdd.Managerite
Static calls · unresolved targets: 1 · external targets: 6.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: bounded manager maps allocation...test sourcelib.pluck.src.bddtest: condition cache allocation fail...test sourcelib.pluck.src.bddtest: manager ITE cache growth quota ...test sourcelib.pluck.src.bddtest: manager ITE limit enforcementtest sourcelib.pluck.src.bddtest: manager ITE operation ceiling r...+3 morebdd.ManageriteLimitExceeded
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsbdd.ManagerglobalSifttest sourcelib.pluck.src.bddtest: localSift returns to best posit...test sourcelib.pluck.src.bddtest: localSift single variablebdd.ManagergetVarPositionbdd.ManagernumVarsbdd.ManagerswapAdjacentVarsbdd.ManagertotalNodeCountbdd.ManagerlocalSift
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersbdd.ManagergetNodebdd.Managerlow
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstest sourcelib.pluck.src.bddtest: CNF benchmark - 3-SAT clausetest sourcelib.pluck.src.bddtest: WmcContext - basic caching corr...test sourcelib.pluck.src.bddtest: WmcContext - cache invalidation...test sourcelib.pluck.src.bddtest: WmcContext - cache size and tri...test sourcelib.pluck.src.bddtest: WmcContext - clear resets every...+103 moreprivate sourcelib.pluck.src.bdd.ManagerinsertCanonicalAssumeCapacityprivate sourcelib.pluck.src.bdd.ManagerprepareVariableInsertbdd.Nodeinitbdd.ManagernewVar
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstest sourcelib.pluck.src.bddtest: newVarAtPositiontest sourcelib.pluck.src.bddtest: newVarAtPosition preserves exis...private sourcelib.pluck.src.bdd.ManagerinsertCanonicalAssumeCapacityprivate sourcelib.pluck.src.bdd.ManagerprepareVariableInsertbdd.Nodeinitbdd.ManagernewVarAtPosition
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: nodesAtLevelbdd.ManagernodesAtLevel
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: binary boolean fast paths avoid...test sourcelib.pluck.src.bddtest: recursive call countingbdd.ManagernumRecursiveCalls
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsbdd.ManagerglobalSiftbdd.ManagerlocalSifttest sourcelib.pluck.src.weighttest: WeightDD ite matches brute forc...test sourcelib.pluck.src.weighttest: WeightDD mul/add match brute fo...bdd.ManagernumVars
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: printStatsbdd.ManagerprintStats
Static calls · unresolved targets: 1 · external targets: 4.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: time limit APIbdd.ManagerresetLimitFlags
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: binary boolean fast paths avoid...test sourcelib.pluck.src.bddtest: recursive call countingbdd.ManagerresetStats
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.pluck.src.bddtest: sequentialCompose behaviorbdd.Managercomposebdd.ManagersequentialCompose
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: time limit APIbdd.ManagersetTimeLimit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.pluck.src.bddtest: sizetest sourcelib.pluck.src.profiling.internal.incrementaltest: BENCHMARK: BDD complexity scali...test sourcelib.pluck.src.profiling.internal.incrementaltest: BENCHMARK: WmcContext persisten...test sourcelib.pluck.src.profiling.internal.incrementaltest: BENCHMARK: XOR chain hard insta...test sourcelib.pluck.src.profiling.internal.incrementaltest: BENCHMARK: conditionHelper cach...test sourcelib.pluck.src.profiling.internal.incrementaltest: BENCHMARK: larger BDD scalingprivate sourcelib.pluck.src.bdd.ManagersizeHelperbdd.Managersize
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstest sourcelib.pluck.src.bddtest: bounded manager maps allocation...test sourcelib.pluck.src.bddtest: condition cache allocation fail...test sourcelib.pluck.src.bddtest: manager ITE cache growth quota ...test sourcelib.pluck.src.bddtest: manager ITE limit enforcementtest sourcelib.pluck.src.bddtest: manager ITE operation ceiling r...+2 morebdd.LimitConfigstartIteLimitbdd.ManagerstartIteLimit
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallstest sourcelib.pluck.src.bddtest: time limit APIbdd.LimitConfigstartTimeLimitbdd.ManagerstartTimeLimit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.pluck.src.bddtest: bounded manager maps allocation...test sourcelib.pluck.src.bddtest: condition cache allocation fail...test sourcelib.pluck.src.bddtest: manager ITE cache growth quota ...test sourcelib.pluck.src.bddtest: manager ITE limit enforcementtest sourcelib.pluck.src.bddtest: manager ITE operation ceiling r...+2 morebdd.LimitConfigstopIteLimitbdd.ManagerstopIteLimit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.pluck.src.bddtest: time limit APIbdd.LimitConfigstopTimeLimitbdd.ManagerstopTimeLimit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsbdd.ManagerlocalSifttest sourcelib.pluck.src.bddtest: swapAdjacentVars basicbdd.ManagerclearCachebdd.ManagergetNodeprivate sourcelib.pluck.src.bdd.ManagergetOrInsertbdd.ManagergetVarAtPositionbdd.ManagertotalNodeCountbdd.Nodeinitbdd.ManagerswapAdjacentVars
Static calls · unresolved targets: 1 · external targets: 7.
Called byCallsNo direct callstest sourcelib.pluck.src.bddtest: time limit APIbdd.ManagertimeLimitExceeded
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.pluck.src.bddtest: toJson - compound formulatest sourcelib.pluck.src.bddtest: toJson - constantstest sourcelib.pluck.src.bddtest: toJson - variableprivate sourcelib.pluck.src.bddwriteBddJsonbdd.ManagertoJson
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.pluck.src.bdd.ManagertoStringHelperbdd.ManagertoString
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsprivate sourcelib.pluck.src.bdd.LessThanHelpercallprivate sourcelib.pluck.src.bdd.ManagerfirstEssentialtest sourcelib.pluck.src.bddtest: newVarAtPositiontest sourcelib.pluck.src.lpsmctest: mixTopKAndSample preserves unbi...private sourcelib.pluck.src.weight.WeightDDbuildFromGuardListInner+7 morebdd.ManagergetNodebdd.ManagertopVar
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callsbdd.ManagerglobalSiftbdd.ManagerlocalSiftbdd.ManagerswapAdjacentVarstest sourcelib.pluck.src.bddtest: totalNodeCounttest sourcelib.pluck.src.profiling.internal.incrementaltest: BENCHMARK: XOR chain hard insta...test sourcelib.pluck.src.profiling.internal.incrementaltest: BENCHMARK: larger BDD scalingbdd.ManagertotalNodeCount
Static calls · unresolved targets: 0 · external targets: 0.

Complete caller list for bdd.Manager.bddAnd

51 direct callers.

Complete caller list for bdd.Manager.bddImplies

7 direct callers.

Complete caller list for bdd.Manager.bddNot

10 direct callers.

Complete caller list for bdd.Manager.bddOr

28 direct callers.

Complete caller list for bdd.Manager.bddXor

7 direct callers.

Complete caller list for bdd.Manager.condition

12 direct callers.

Complete caller list for bdd.Manager.deinit

170 direct callers.

Complete caller list for bdd.Manager.eq

31 direct callers.

Complete caller list for bdd.Manager.getNode

12 direct callers.

Complete caller list for bdd.Manager.getVarPosition

8 direct callers.

Complete caller list for bdd.Manager.init

175 direct callers.

Complete caller list for bdd.Manager.ite

7 direct callers.

Complete call list for bdd.Manager.ite

9 direct calls.

Complete caller list for bdd.Manager.iteLimitExceeded

8 direct callers.

Complete caller list for bdd.Manager.newVar

108 direct callers.

Complete caller list for bdd.Manager.startIteLimit

7 direct callers.

Complete caller list for bdd.Manager.stopIteLimit

7 direct callers.

Complete caller list for bdd.Manager.topVar

12 direct callers.

Audit

Definitions49
Public names49
Members16
Version26.7.0
Revisiondaab053ee433