pub trait BooleanFunction: Function {
Show 49 methods
// Required methods
fn f_edge<'id>(manager: &Self::Manager<'id>) -> EdgeOfFunc<'id, Self>;
fn t_edge<'id>(manager: &Self::Manager<'id>) -> EdgeOfFunc<'id, Self>;
fn var_edge<'id>(
manager: &Self::Manager<'id>,
var: VarNo,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn not_edge<'id>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn and_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn or_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn nand_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn nor_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn xor_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn equiv_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn imp_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn imp_strict_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn sat_count_edge<'id, N: SatCountNumber, S: BuildHasher>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
vars: LevelNo,
cache: &mut SatCountCache<N, S>,
) -> N;
fn pick_cube_edge<'id>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
choice: impl FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool,
) -> Option<Vec<OptBool>>;
fn pick_cube_dd_edge<'id>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
choice: impl FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn pick_cube_dd_set_edge<'id>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
literal_set: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>;
fn eval_edge<'id>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
args: impl IntoIterator<Item = (VarNo, bool)>,
) -> bool;
// Provided methods
fn f<'id>(manager: &Self::Manager<'id>) -> Self { ... }
fn t<'id>(manager: &Self::Manager<'id>) -> Self { ... }
fn var<'id>(manager: &Self::Manager<'id>, var: VarNo) -> AllocResult<Self> { ... }
fn not_var<'id>(
manager: &Self::Manager<'id>,
var: VarNo,
) -> AllocResult<Self> { ... }
fn cofactors(&self) -> Option<(Self, Self)> { ... }
fn cofactor_true(&self) -> Option<Self> { ... }
fn cofactor_false(&self) -> Option<Self> { ... }
fn not(&self) -> AllocResult<Self> { ... }
fn not_owned(self) -> AllocResult<Self> { ... }
fn and(&self, rhs: &Self) -> AllocResult<Self> { ... }
fn or(&self, rhs: &Self) -> AllocResult<Self> { ... }
fn nand(&self, rhs: &Self) -> AllocResult<Self> { ... }
fn nor(&self, rhs: &Self) -> AllocResult<Self> { ... }
fn xor(&self, rhs: &Self) -> AllocResult<Self> { ... }
fn equiv(&self, rhs: &Self) -> AllocResult<Self> { ... }
fn imp(&self, rhs: &Self) -> AllocResult<Self> { ... }
fn imp_strict(&self, rhs: &Self) -> AllocResult<Self> { ... }
fn not_var_edge<'id>(
manager: &Self::Manager<'id>,
var: VarNo,
) -> AllocResult<EdgeOfFunc<'id, Self>> { ... }
fn cofactors_edge<'a, 'id>(
manager: &'a Self::Manager<'id>,
f: &'a EdgeOfFunc<'id, Self>,
) -> Option<(Borrowed<'a, EdgeOfFunc<'id, Self>>, Borrowed<'a, EdgeOfFunc<'id, Self>>)> { ... }
fn cofactors_node<'a, 'id>(
tag: ETagOfFunc<'id, Self>,
node: &'a INodeOfFunc<'id, Self>,
) -> (Borrowed<'a, EdgeOfFunc<'id, Self>>, Borrowed<'a, EdgeOfFunc<'id, Self>>) { ... }
fn not_edge_owned<'id>(
manager: &Self::Manager<'id>,
edge: EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>> { ... }
fn satisfiable(&self) -> bool { ... }
fn valid(&self) -> bool { ... }
fn ite(&self, then_case: &Self, else_case: &Self) -> AllocResult<Self> { ... }
fn ite_edge<'id>(
manager: &Self::Manager<'id>,
if_edge: &EdgeOfFunc<'id, Self>,
then_edge: &EdgeOfFunc<'id, Self>,
else_edge: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>> { ... }
fn sat_count<N: SatCountNumber, S: BuildHasher>(
&self,
vars: LevelNo,
cache: &mut SatCountCache<N, S>,
) -> N { ... }
fn pick_cube(
&self,
choice: impl for<'id> FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool,
) -> Option<Vec<OptBool>> { ... }
fn pick_cube_dd(
&self,
choice: impl for<'id> FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool,
) -> AllocResult<Self> { ... }
fn pick_cube_dd_set(&self, literal_set: &Self) -> AllocResult<Self> { ... }
fn pick_cube_uniform<S: BuildHasher>(
&self,
cache: &mut SatCountCache<F64, S>,
rng: &mut Rng,
) -> Option<Vec<OptBool>> { ... }
fn pick_cube_uniform_edge<'id, S: BuildHasher>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
cache: &mut SatCountCache<F64, S>,
rng: &mut Rng,
) -> Option<Vec<OptBool>> { ... }
fn eval(&self, args: impl IntoIterator<Item = (VarNo, bool)>) -> bool { ... }
}
Expand description
Boolean functions 𝔹ⁿ → 𝔹
As a user of this trait, you are probably most interested in methods like
Self::not()
, Self::and()
, and Self::or()
. As an implementor, it
suffices to implement the functions operating on edges.
Required Methods§
Sourcefn f_edge<'id>(manager: &Self::Manager<'id>) -> EdgeOfFunc<'id, Self>
fn f_edge<'id>(manager: &Self::Manager<'id>) -> EdgeOfFunc<'id, Self>
Get the always false function ⊥
as edge
Sourcefn t_edge<'id>(manager: &Self::Manager<'id>) -> EdgeOfFunc<'id, Self>
fn t_edge<'id>(manager: &Self::Manager<'id>) -> EdgeOfFunc<'id, Self>
Get the always true function ⊤
as edge
Sourcefn var_edge<'id>(
manager: &Self::Manager<'id>,
var: VarNo,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn var_edge<'id>( manager: &Self::Manager<'id>, var: VarNo, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Get the Boolean function (as edge) that is true if and only if var
is
true
Panics if var
is greater or equal to the number of variables in
manager
.
Sourcefn not_edge<'id>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn not_edge<'id>( manager: &Self::Manager<'id>, edge: &EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Compute the negation ¬edge
, edge version
Sourcefn and_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn and_edge<'id>( manager: &Self::Manager<'id>, lhs: &EdgeOfFunc<'id, Self>, rhs: &EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Compute the conjunction lhs ∧ rhs
, edge version
Sourcefn or_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn or_edge<'id>( manager: &Self::Manager<'id>, lhs: &EdgeOfFunc<'id, Self>, rhs: &EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Compute the disjunction lhs ∨ rhs
, edge version
Sourcefn nand_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn nand_edge<'id>( manager: &Self::Manager<'id>, lhs: &EdgeOfFunc<'id, Self>, rhs: &EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Compute the negated conjunction lhs ⊼ rhs
, edge version
Sourcefn nor_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn nor_edge<'id>( manager: &Self::Manager<'id>, lhs: &EdgeOfFunc<'id, Self>, rhs: &EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Compute the negated disjunction lhs ⊽ rhs
, edge version
Sourcefn xor_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn xor_edge<'id>( manager: &Self::Manager<'id>, lhs: &EdgeOfFunc<'id, Self>, rhs: &EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Compute the exclusive disjunction lhs ⊕ rhs
, edge version
Sourcefn equiv_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn equiv_edge<'id>( manager: &Self::Manager<'id>, lhs: &EdgeOfFunc<'id, Self>, rhs: &EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Compute the equivalence lhs ↔ rhs
, edge version
Sourcefn imp_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn imp_edge<'id>( manager: &Self::Manager<'id>, lhs: &EdgeOfFunc<'id, Self>, rhs: &EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Compute the implication lhs → rhs
, edge version
Sourcefn imp_strict_edge<'id>(
manager: &Self::Manager<'id>,
lhs: &EdgeOfFunc<'id, Self>,
rhs: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn imp_strict_edge<'id>( manager: &Self::Manager<'id>, lhs: &EdgeOfFunc<'id, Self>, rhs: &EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Compute the strict implication lhs < rhs
, edge version
Sourcefn sat_count_edge<'id, N: SatCountNumber, S: BuildHasher>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
vars: LevelNo,
cache: &mut SatCountCache<N, S>,
) -> N
fn sat_count_edge<'id, N: SatCountNumber, S: BuildHasher>( manager: &Self::Manager<'id>, edge: &EdgeOfFunc<'id, Self>, vars: LevelNo, cache: &mut SatCountCache<N, S>, ) -> N
Edge
version of Self::sat_count()
Sourcefn pick_cube_edge<'id>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
choice: impl FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool,
) -> Option<Vec<OptBool>>
fn pick_cube_edge<'id>( manager: &Self::Manager<'id>, edge: &EdgeOfFunc<'id, Self>, choice: impl FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool, ) -> Option<Vec<OptBool>>
Edge
version of Self::pick_cube()
Sourcefn pick_cube_dd_edge<'id>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
choice: impl FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn pick_cube_dd_edge<'id>( manager: &Self::Manager<'id>, edge: &EdgeOfFunc<'id, Self>, choice: impl FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Edge
version of Self::pick_cube_dd()
Sourcefn pick_cube_dd_set_edge<'id>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
literal_set: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn pick_cube_dd_set_edge<'id>( manager: &Self::Manager<'id>, edge: &EdgeOfFunc<'id, Self>, literal_set: &EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Edge
version of Self::pick_cube_dd_set()
Sourcefn eval_edge<'id>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
args: impl IntoIterator<Item = (VarNo, bool)>,
) -> bool
fn eval_edge<'id>( manager: &Self::Manager<'id>, edge: &EdgeOfFunc<'id, Self>, args: impl IntoIterator<Item = (VarNo, bool)>, ) -> bool
Edge
version of Self::eval()
Provided Methods§
Sourcefn var<'id>(manager: &Self::Manager<'id>, var: VarNo) -> AllocResult<Self>
fn var<'id>(manager: &Self::Manager<'id>, var: VarNo) -> AllocResult<Self>
Get the Boolean function that is true if and only if var
is true
Panics if var
is greater or equal to the number of variables in
manager
.
Sourcefn not_var<'id>(manager: &Self::Manager<'id>, var: VarNo) -> AllocResult<Self>
fn not_var<'id>(manager: &Self::Manager<'id>, var: VarNo) -> AllocResult<Self>
Get the Boolean function that is true if and only if var
is false
Panics if var
is greater or equal to the number of variables in
manager
.
Sourcefn cofactors(&self) -> Option<(Self, Self)>
fn cofactors(&self) -> Option<(Self, Self)>
Get the cofactors (f_true, f_false)
of self
Let f(x₀, …, xₙ) be represented by self
, where x₀ is (currently) the
top-most variable. Then ftrue(x₁, …, xₙ) = f(⊤, x₁, …, xₙ)
and ffalse(x₁, …, xₙ) = f(⊥, x₁, …, xₙ).
Note that the domain of f is 𝔹ⁿ⁺¹ while the domain of ftrue and ffalse is 𝔹ⁿ. This is irrelevant in case of BDDs and BCDDs, but not for ZBDDs: For instance, g(x₀) = x₀ and g’(x₀, x₁) = x₀ have the same representation as BDDs or BCDDs, but different representations as ZBDDs.
Structurally, the cofactors are simply the children in case of BDDs and ZBDDs. (For BCDDs, the edge tags are adjusted accordingly.) On these representations, runtime is thus in O(1).
Returns None
iff self
references a terminal node. If you only need
f_true
or f_false
, Self::cofactor_true
or
Self::cofactor_false
are slightly more efficient.
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn cofactor_true(&self) -> Option<Self>
fn cofactor_true(&self) -> Option<Self>
Get the cofactor f_true
of self
This method is slightly more efficient than Self::cofactors
in case
f_false
is not needed.
For a more detailed description, see Self::cofactors
.
Returns None
iff self
references a terminal node.
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn cofactor_false(&self) -> Option<Self>
fn cofactor_false(&self) -> Option<Self>
Get the cofactor f_false
of self
This method is slightly more efficient than Self::cofactors
in case
f_true
is not needed.
For a more detailed description, see Self::cofactors
.
Returns None
iff self
references a terminal node.
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn not(&self) -> AllocResult<Self>
fn not(&self) -> AllocResult<Self>
Compute the negation ¬self
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn not_owned(self) -> AllocResult<Self>
fn not_owned(self) -> AllocResult<Self>
Compute the negation ¬self
, owned version
Compared to Self::not()
, this method does not need to clone the
function, so when the implementation is using (e.g.) complemented edges,
this might be a little bit faster than Self::not()
.
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn and(&self, rhs: &Self) -> AllocResult<Self>
fn and(&self, rhs: &Self) -> AllocResult<Self>
Compute the conjunction self ∧ rhs
Locking behavior: acquires the manager’s lock for shared access.
Panics if self
and rhs
don’t belong to the same manager.
Sourcefn or(&self, rhs: &Self) -> AllocResult<Self>
fn or(&self, rhs: &Self) -> AllocResult<Self>
Compute the disjunction self ∨ rhs
Locking behavior: acquires the manager’s lock for shared access.
Panics if self
and rhs
don’t belong to the same manager.
Sourcefn nand(&self, rhs: &Self) -> AllocResult<Self>
fn nand(&self, rhs: &Self) -> AllocResult<Self>
Compute the negated conjunction self ⊼ rhs
Locking behavior: acquires the manager’s lock for shared access.
Panics if self
and rhs
don’t belong to the same manager.
Sourcefn nor(&self, rhs: &Self) -> AllocResult<Self>
fn nor(&self, rhs: &Self) -> AllocResult<Self>
Compute the negated disjunction self ⊽ rhs
Locking behavior: acquires the manager’s lock for shared access.
Panics if self
and rhs
don’t belong to the same manager.
Sourcefn xor(&self, rhs: &Self) -> AllocResult<Self>
fn xor(&self, rhs: &Self) -> AllocResult<Self>
Compute the exclusive disjunction self ⊕ rhs
Locking behavior: acquires the manager’s lock for shared access.
Panics if self
and rhs
don’t belong to the same manager.
Sourcefn equiv(&self, rhs: &Self) -> AllocResult<Self>
fn equiv(&self, rhs: &Self) -> AllocResult<Self>
Compute the equivalence self ↔ rhs
Locking behavior: acquires the manager’s lock for shared access.
Panics if self
and rhs
don’t belong to the same manager.
Sourcefn imp(&self, rhs: &Self) -> AllocResult<Self>
fn imp(&self, rhs: &Self) -> AllocResult<Self>
Compute the implication self → rhs
(or self ≤ rhs
)
Locking behavior: acquires the manager’s lock for shared access.
Panics if self
and rhs
don’t belong to the same manager.
Sourcefn imp_strict(&self, rhs: &Self) -> AllocResult<Self>
fn imp_strict(&self, rhs: &Self) -> AllocResult<Self>
Compute the strict implication self < rhs
Locking behavior: acquires the manager’s lock for shared access.
Panics if self
and rhs
don’t belong to the same manager.
Sourcefn not_var_edge<'id>(
manager: &Self::Manager<'id>,
var: VarNo,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn not_var_edge<'id>( manager: &Self::Manager<'id>, var: VarNo, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Get the Boolean function (as edge) that is true if and only if var
is
false
Panics if var
is greater or equal to the number of variables in
manager
.
Sourcefn cofactors_edge<'a, 'id>(
manager: &'a Self::Manager<'id>,
f: &'a EdgeOfFunc<'id, Self>,
) -> Option<(Borrowed<'a, EdgeOfFunc<'id, Self>>, Borrowed<'a, EdgeOfFunc<'id, Self>>)>
fn cofactors_edge<'a, 'id>( manager: &'a Self::Manager<'id>, f: &'a EdgeOfFunc<'id, Self>, ) -> Option<(Borrowed<'a, EdgeOfFunc<'id, Self>>, Borrowed<'a, EdgeOfFunc<'id, Self>>)>
Get the cofactors (f_true, f_false)
of f
, edge version
Returns None
iff f
references a terminal node. For more details on
the semantics of f_true
and f_false
, see Self::cofactors
.
Sourcefn cofactors_node<'a, 'id>(
tag: ETagOfFunc<'id, Self>,
node: &'a INodeOfFunc<'id, Self>,
) -> (Borrowed<'a, EdgeOfFunc<'id, Self>>, Borrowed<'a, EdgeOfFunc<'id, Self>>)
fn cofactors_node<'a, 'id>( tag: ETagOfFunc<'id, Self>, node: &'a INodeOfFunc<'id, Self>, ) -> (Borrowed<'a, EdgeOfFunc<'id, Self>>, Borrowed<'a, EdgeOfFunc<'id, Self>>)
Get the cofactors (f_true, f_false)
of node
, assuming an incoming
edge with EdgeTag
Returns None
iff f
references a terminal node. For more details on
the semantics of f_true
and f_false
, see Self::cofactors
.
Implementation note: The default implementation assumes that
cofactor 0 corresponds to f_true
and
cofactor 1 corresponds to f_false
.
Sourcefn not_edge_owned<'id>(
manager: &Self::Manager<'id>,
edge: EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn not_edge_owned<'id>( manager: &Self::Manager<'id>, edge: EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Compute the negation ¬edge
, owned edge version
Compared to Self::not_edge()
, this method does not need to clone the
edge, so when the implementation is using (e.g.) complemented edges,
this might be a little bit faster than Self::not_edge()
.
Sourcefn satisfiable(&self) -> bool
fn satisfiable(&self) -> bool
Returns true
iff self
is satisfiable, i.e. is not ⊥
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn valid(&self) -> bool
fn valid(&self) -> bool
Returns true
iff self
is valid, i.e. is ⊤
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn ite(&self, then_case: &Self, else_case: &Self) -> AllocResult<Self>
fn ite(&self, then_case: &Self, else_case: &Self) -> AllocResult<Self>
Compute if self { then_case } else { else_case }
This is equivalent to (self ∧ then_case) ∨ (¬self ∧ else_case)
but
possibly more efficient than computing all the
conjunctions/disjunctions.
Locking behavior: acquires the manager’s lock for shared access.
Panics if self
, then_case
, and else_case
don’t belong to the same
manager.
Sourcefn ite_edge<'id>(
manager: &Self::Manager<'id>,
if_edge: &EdgeOfFunc<'id, Self>,
then_edge: &EdgeOfFunc<'id, Self>,
else_edge: &EdgeOfFunc<'id, Self>,
) -> AllocResult<EdgeOfFunc<'id, Self>>
fn ite_edge<'id>( manager: &Self::Manager<'id>, if_edge: &EdgeOfFunc<'id, Self>, then_edge: &EdgeOfFunc<'id, Self>, else_edge: &EdgeOfFunc<'id, Self>, ) -> AllocResult<EdgeOfFunc<'id, Self>>
Compute if if_edge { then_edge } else { else_edge }
(edge version)
This is equivalent to (self ∧ then_case) ∨ (¬self ∧ else_case)
but
possibly more efficient than computing all the
conjunctions/disjunctions.
Sourcefn sat_count<N: SatCountNumber, S: BuildHasher>(
&self,
vars: LevelNo,
cache: &mut SatCountCache<N, S>,
) -> N
fn sat_count<N: SatCountNumber, S: BuildHasher>( &self, vars: LevelNo, cache: &mut SatCountCache<N, S>, ) -> N
Count the number of satisfying assignments, assuming vars
input
variables
The cache
can be used to speed up multiple model counting operations
for functions in the same decision diagram. If the model counts of just
one function are of interest, one may simply pass an empty
SatCountCache
(using &mut SatCountCache::default()
). The cache
will automatically be invalidated in case there have been reordering
operations or vars
changed since the last query (see
SatCountCache::clear_if_invalid()
). Still, it is the caller’s
responsibility to not use the cache for different managers.
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn pick_cube(
&self,
choice: impl for<'id> FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool,
) -> Option<Vec<OptBool>>
fn pick_cube( &self, choice: impl for<'id> FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool, ) -> Option<Vec<OptBool>>
Pick a cube of this function
A cube c
of a function f
is a satisfying assignment, i.e., c → f
holds, and can be represented as a conjunction of literals. It does
not necessarily define all variables in the function’s domain (it is
not necessarily a canonical minterm). For most (if not all) kinds of
decision diagrams, cubes have at most one node per level.
Returns None
if the function is false. Otherwise, this method returns
a vector where the i-th entry indicates whether the i-th variable is
true, false, or “don’t care.”
Whenever a value for a variable needs to be chosen (i.e., it cannot be
left as a don’t care), choice
is called to determine the valuation for
this variable. The argument of type LevelNo
is the level
corresponding to that variable. It is guaranteed that choice
will
only be called at most once for each level. The Edge
argument is
guaranteed to point to an inner node at the respective level. (We
pass an Edge
and not an InnerNode
reference since Edge
s
provide more information, e.g., the NodeID
.)
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn pick_cube_dd(
&self,
choice: impl for<'id> FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool,
) -> AllocResult<Self>
fn pick_cube_dd( &self, choice: impl for<'id> FnMut(&Self::Manager<'id>, &EdgeOfFunc<'id, Self>, LevelNo) -> bool, ) -> AllocResult<Self>
Pick a symbolic cube of this function, i.e., as decision diagram
A cube c
of a function f
is a satisfying assignment, i.e., c → f
holds, and can be represented as a conjunction of literals. It does
not necessarily define all variables in the function’s domain (it is
not necessarily a canonical minterm). For most (if not all) kinds of
decision diagrams, cubes have at most one node per level.
Whenever a value for a variable needs to be chosen (i.e., it cannot be
left as a don’t care), choice
is called to determine the valuation for
this variable. The argument of type LevelNo
is the level
corresponding to that variable. It is guaranteed that choice
will
only be called at most once for each level. The Edge
argument is
guaranteed to point to an inner node at the respective level. (We
pass an Edge
and not an InnerNode
reference since Edge
s
provide more information, e.g., the NodeID
.)
If self
is ⊥
, then the return value will be ⊥
.
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn pick_cube_dd_set(&self, literal_set: &Self) -> AllocResult<Self>
fn pick_cube_dd_set(&self, literal_set: &Self) -> AllocResult<Self>
Pick a symbolic cube of this function, i.e., as decision diagram, using
the literals in literal_set
if there is a choice
A cube c
of a function f
is a satisfying assignment, i.e., c → f
holds, and can be represented as a conjunction of literals. It does
not necessarily define all variables in the function’s domain (it is
not necessarily a canonical minterm). For most (if not all) kinds of
decision diagrams, cubes have at most one node per level.
literal_set
is represented as a conjunction of literals. Whenever
there is a choice for a variable, it will be set to true if the variable
has a positive occurrence in literal_set
, and set to false if it
occurs negated in literal_set
. If the variable does not occur in
literal_set
, then it will be left as don’t care if possible, otherwise
an arbitrary (not necessarily random) choice will be performed.
If self
is ⊥
, then the return value will be ⊥
.
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn pick_cube_uniform<S: BuildHasher>(
&self,
cache: &mut SatCountCache<F64, S>,
rng: &mut Rng,
) -> Option<Vec<OptBool>>
fn pick_cube_uniform<S: BuildHasher>( &self, cache: &mut SatCountCache<F64, S>, rng: &mut Rng, ) -> Option<Vec<OptBool>>
Pick a random cube of this function, where each cube has the same probability of being chosen
Returns None
if the function is false. Otherwise, this method returns
a vector where the i-th entry indicates whether the i-th variable is
true, false, or “don’t care.” To obtain a total valuation from this
partial valuation, it suffices to pick true or false with probability ½.
(Note that this function returns a partial valuation with n “don’t
cares” with a probability that is 2n as high as the
probability of any total valuation.)
Locking behavior: acquires the manager’s lock for shared access.
Sourcefn pick_cube_uniform_edge<'id, S: BuildHasher>(
manager: &Self::Manager<'id>,
edge: &EdgeOfFunc<'id, Self>,
cache: &mut SatCountCache<F64, S>,
rng: &mut Rng,
) -> Option<Vec<OptBool>>
fn pick_cube_uniform_edge<'id, S: BuildHasher>( manager: &Self::Manager<'id>, edge: &EdgeOfFunc<'id, Self>, cache: &mut SatCountCache<F64, S>, rng: &mut Rng, ) -> Option<Vec<OptBool>>
Edge
version of Self::pick_cube_uniform()
Sourcefn eval(&self, args: impl IntoIterator<Item = (VarNo, bool)>) -> bool
fn eval(&self, args: impl IntoIterator<Item = (VarNo, bool)>) -> bool
Evaluate this Boolean function
args
consists of pairs (variable, value)
and determines the
valuation for all variables in the function’s domain. The order is
irrelevant (except that if the valuation for a variable is given
multiple times, the last value counts).
Note that the domain of the Boolean function represented by self
is
implicit and may comprise a strict subset of the variables in the
manager only. This method assumes that the function’s domain
corresponds the set of variables in args
. Remember that there are
kinds of decision diagrams (e.g., ZBDDs) where the domain plays a
crucial role for the interpretation of decision diagram nodes as a
Boolean function. On the other hand, extending the domain of, e.g.,
ordinary BDDs does not affect the evaluation result.
Should there be a decision node for a variable not part of the domain,
then false
is used as the decision value.
Locking behavior: acquires the manager’s lock for shared access.
Panics if any variable number in args
is larger that the number of
variables in the containing manager.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.