Struct biodivine_lib_bdd::Bdd
source · [−]Expand description
An array-based encoding of the binary decision diagram implementing basic logical operations.
To create Bdd
s for atomic formulas, use a BddVariableSet
.
Tuple Fields
0: Vec<BddNode>
Implementations
sourceimpl Bdd
impl Bdd
Basic boolean logical operations for Bdd
s:
$\neg, \land, \lor, \Rightarrow, \Leftrightarrow, \oplus$.
sourcepub fn not(&self) -> Bdd
pub fn not(&self) -> Bdd
Create a Bdd
corresponding to the $\neg \phi$ formula, where $\phi$ is this Bdd
.
sourcepub fn and(&self, right: &Bdd) -> Bdd
pub fn and(&self, right: &Bdd) -> Bdd
Create a Bdd
corresponding to the $\phi \land \psi$ formula, where $\phi$ and $\psi$
are the two given Bdd
s.
sourcepub fn or(&self, right: &Bdd) -> Bdd
pub fn or(&self, right: &Bdd) -> Bdd
Create a Bdd
corresponding to the $\phi \lor \psi$ formula, where $\phi$ and $\psi$
are the two given Bdd
s.
sourcepub fn imp(&self, right: &Bdd) -> Bdd
pub fn imp(&self, right: &Bdd) -> Bdd
Create a Bdd
corresponding to the $\phi \Rightarrow \psi$ formula, where $\phi$ and $\psi$
are the two given Bdd
s.
sourcepub fn iff(&self, right: &Bdd) -> Bdd
pub fn iff(&self, right: &Bdd) -> Bdd
Create a Bdd
corresponding to the $\phi \Leftrightarrow \psi$ formula, where $\phi$ and $\psi$
are the two given Bdd
s.
sourcepub fn xor(&self, right: &Bdd) -> Bdd
pub fn xor(&self, right: &Bdd) -> Bdd
Create a Bdd
corresponding to the $\phi \oplus \psi$ formula, where $\phi$ and $\psi$
are the two given Bdd
s.
sourcepub fn and_not(&self, right: &Bdd) -> Bdd
pub fn and_not(&self, right: &Bdd) -> Bdd
Create a Bdd
corresponding to the $\phi \land \neg \psi$ formula, where $\phi$ and $\psi$
are the two given Bdd
s.
sourcepub fn binary_op<T>(left: &Bdd, right: &Bdd, op_function: T) -> Bdd where
T: Fn(Option<bool>, Option<bool>) -> Option<bool>,
pub fn binary_op<T>(left: &Bdd, right: &Bdd, op_function: T) -> Bdd where
T: Fn(Option<bool>, Option<bool>) -> Option<bool>,
Apply a general binary operation to two given Bdd
objects.
The op_function
specifies the actual logical operation that will be performed. See
crate::op_function
module for examples.
In general, this function can be used to slightly speed up less common Boolean operations or to fuse together several operations (like negation and binary operation).
sourcepub fn fused_binary_flip_op<T>(
left: (&Bdd, Option<BddVariable>),
right: (&Bdd, Option<BddVariable>),
flip_output: Option<BddVariable>,
op_function: T
) -> Bdd where
T: Fn(Option<bool>, Option<bool>) -> Option<bool>,
pub fn fused_binary_flip_op<T>(
left: (&Bdd, Option<BddVariable>),
right: (&Bdd, Option<BddVariable>),
flip_output: Option<BddVariable>,
op_function: T
) -> Bdd where
T: Fn(Option<bool>, Option<bool>) -> Option<bool>,
Apply a general binary operation together with up-to three Bdd variable flips. See also binary_op
.
A flip exchanges the edges of all decision nodes with the specified variable x
.
As a result, the set of bitvectors represented by this Bdd has the value of x
negated.
With this operation, you can apply such flip to both input operands as well as the output Bdd. This can greatly simplify implementation of state space generators for asynchronous systems.
sourceimpl Bdd
impl Bdd
sourcepub fn ternary_op<T>(a: &Bdd, b: &Bdd, c: &Bdd, op_function: T) -> Bdd where
T: Fn(Option<bool>, Option<bool>, Option<bool>) -> Option<bool>,
pub fn ternary_op<T>(a: &Bdd, b: &Bdd, c: &Bdd, op_function: T) -> Bdd where
T: Fn(Option<bool>, Option<bool>, Option<bool>) -> Option<bool>,
A ternary logical operation on three Bdd
objects. Works the same as Bdd::binary_op
,
but with three arguments.
Note that this may not necessarily be faster than performing two (or more) binary operations. However, in some cases it can significantly reduce overhead incurred by creating large intermediate decision diagrams.
sourcepub fn fused_ternary_flip_op<T>(
a: (&Bdd, Option<BddVariable>),
b: (&Bdd, Option<BddVariable>),
c: (&Bdd, Option<BddVariable>),
flip_output: Option<BddVariable>,
op_function: T
) -> Bdd where
T: Fn(Option<bool>, Option<bool>, Option<bool>) -> Option<bool>,
pub fn fused_ternary_flip_op<T>(
a: (&Bdd, Option<BddVariable>),
b: (&Bdd, Option<BddVariable>),
c: (&Bdd, Option<BddVariable>),
flip_output: Option<BddVariable>,
op_function: T
) -> Bdd where
T: Fn(Option<bool>, Option<bool>, Option<bool>) -> Option<bool>,
A ternary version of Bdd::fused_binary_flip_op
that makes it possible to flip
the meaning of a single variable the input and output diagrams.
Note that this may not necessarily be faster than performing two (or more) binary operations. However, in some cases it can significantly reduce overhead incurred by creating large intermediate decision diagrams.
sourceimpl Bdd
impl Bdd
Advanced relation-like operations for Bdd
s.
sourcepub fn var_project(&self, variable: BddVariable) -> Bdd
pub fn var_project(&self, variable: BddVariable) -> Bdd
Eliminates one given variable from the Bdd
.
If we see the Bdd as a set of bitvectors, this is essentially existential quantification: $\exists x_i : (x_1, …, x_i, …, x_n) \in BDD$.
sourcepub fn project(&self, variables: &[BddVariable]) -> Bdd
pub fn project(&self, variables: &[BddVariable]) -> Bdd
Eliminate all given variables from the Bdd
. This is a generalized variant
of var_projection
.
This can be used to implement operations like domain
and range
of
a certain relation.
sourcepub fn var_pick(&self, variable: BddVariable) -> Bdd
pub fn var_pick(&self, variable: BddVariable) -> Bdd
Picks one valuation for the given BddVariable
.
Essentially, what this means is that $(x_1, …, x_i, …, x_n) \in B \Leftrightarrow (x_1, …, \neg x_i, …, x_n) \not\in B$. That is, each valuation (without $x_i$) can be present only with either $x_i = 1$ or $x_i = 0$, but not both.
WARNING! var_pick
is a bit troublesome in terms of composition: B.var_pick(x).var_pick(y)
is probably not what you think. So make sure to prove and test thoroughly.
sourcepub fn var_pick_random<R: Rng>(&self, variable: BddVariable, rng: &mut R) -> Bdd
pub fn var_pick_random<R: Rng>(&self, variable: BddVariable, rng: &mut R) -> Bdd
Same as bdd.var_pick
, but the preferred value is picked randomly using
the provided generator, instead of defaulting to false
.
Note that this is not the same as having a random value picked on each path in the Bdd
.
Instead, there is one “global” value that is preferred on every path.
sourcepub fn pick(&self, variables: &[BddVariable]) -> Bdd
pub fn pick(&self, variables: &[BddVariable]) -> Bdd
Picks one “witness” valuation for the given variables. This is a generalized variant
of var_pick
.
After this operation, if we view Bdd
as a set of bitvectors, every partial valuation in
the original Bdd
, disregarding the given variables
, has exactly one witness valuation
in the result, which was also in the original Bdd
.
This can be used to implement non-trivial element picking on relations (for example, for $A \times B$, picking one $b \in B$ for every $a \in A$).
sourcepub fn pick_random<R: Rng>(&self, variables: &[BddVariable], rng: &mut R) -> Bdd
pub fn pick_random<R: Rng>(&self, variables: &[BddVariable], rng: &mut R) -> Bdd
Same as bdd.pick
, but the preferred value for each variable is picked randomly using
the provided generator.
sourcepub fn var_select(&self, variable: BddVariable, value: bool) -> Bdd
pub fn var_select(&self, variable: BddVariable, value: bool) -> Bdd
Fix the value of a specific BddVariable
to the given value
. This is just a shorthand
for $B \land (x \Leftrightarrow \texttt{value})$.
sourcepub fn select(&self, variables: &[(BddVariable, bool)]) -> Bdd
pub fn select(&self, variables: &[(BddVariable, bool)]) -> Bdd
Generalized operation to var_select
, allows effectively fixing multiple variables to
the given values. Similar to BddValuation.into::<Bdd>()
, but here you don’t have to
specify all variables.
sourcepub fn var_restrict(&self, variable: BddVariable, value: bool) -> Bdd
pub fn var_restrict(&self, variable: BddVariable, value: bool) -> Bdd
Fixes a variable
to the given value
, and then eliminates said variable using projection.
A valuation v
satisfies the resulting formula B'
if and only if v[variable = value]
satisfied the original formula B
.
sourceimpl Bdd
impl Bdd
.dot
export procedure for Bdd
s.
sourcepub fn write_as_dot_string(
&self,
output: &mut dyn Write,
variables: &BddVariableSet,
zero_pruned: bool
) -> Result<(), Error>
pub fn write_as_dot_string(
&self,
output: &mut dyn Write,
variables: &BddVariableSet,
zero_pruned: bool
) -> Result<(), Error>
Output this Bdd
as a .dot
string into the given output
writer.
Variable names in the graph are resolved from the given BddVariableSet
.
If zero_pruned
is true, edges leading to zero
are not shown. This can greatly
simplify the graph without losing information.
sourcepub fn to_dot_string(
&self,
variables: &BddVariableSet,
zero_pruned: bool
) -> String
pub fn to_dot_string(
&self,
variables: &BddVariableSet,
zero_pruned: bool
) -> String
Convert this Bdd
to a .dot
string.
Variable names in the graph are resolved from the given BddVariableSet
.
If zero_pruned
is true, edges leading to zero
are not shown. This can greatly
simplify the graph without losing information.
sourceimpl Bdd
impl Bdd
Serialisation and deserialisation methods for Bdd
s.
sourcepub fn write_as_string(&self, output: &mut dyn Write) -> Result<(), Error>
pub fn write_as_string(&self, output: &mut dyn Write) -> Result<(), Error>
Write this Bdd
into the given output
writer using a simple string format.
sourcepub fn read_as_string(input: &mut dyn Read) -> Result<Bdd, String>
pub fn read_as_string(input: &mut dyn Read) -> Result<Bdd, String>
Read a Bdd
from the given input
reader, assuming a simple string format.
sourcepub fn write_as_bytes(&self, output: &mut dyn Write) -> Result<(), Error>
pub fn write_as_bytes(&self, output: &mut dyn Write) -> Result<(), Error>
Write this Bdd
into the given output
writer using a simple little-endian binary encoding.
sourcepub fn read_as_bytes(input: &mut dyn Read) -> Result<Bdd, Error>
pub fn read_as_bytes(input: &mut dyn Read) -> Result<Bdd, Error>
Read a Bdd
from a given input
reader using a simple little-endian binary encoding.
sourcepub fn from_string(bdd: &str) -> Bdd
pub fn from_string(bdd: &str) -> Bdd
Read a Bdd
from a serialized string.
sourceimpl Bdd
impl Bdd
Several useful (mostly internal) low-level utility methods for Bdd
s.
pub fn exact_cardinality(&self) -> BigInt
sourcepub fn cardinality(&self) -> f64
pub fn cardinality(&self) -> f64
Approximately computes the number of valuations satisfying the formula given
by this Bdd
.
sourcepub fn sat_witness(&self) -> Option<BddValuation>
pub fn sat_witness(&self) -> Option<BddValuation>
If the Bdd
is satisfiable, return some BddValuation
that satisfies the Bdd
.
sourcepub fn to_boolean_expression(
&self,
variables: &BddVariableSet
) -> BooleanExpression
pub fn to_boolean_expression(
&self,
variables: &BddVariableSet
) -> BooleanExpression
Convert this Bdd
to a BooleanExpression
(using the variable names from the given
BddVariableSet
).
sourcepub(crate) fn root_pointer(&self) -> BddPointer
pub(crate) fn root_pointer(&self) -> BddPointer
(internal) Pointer to the root of the decision diagram.
sourcepub(crate) fn low_link_of(&self, node: BddPointer) -> BddPointer
pub(crate) fn low_link_of(&self, node: BddPointer) -> BddPointer
(internal) Get the low link of the node at a specified location.
sourcepub(crate) fn high_link_of(&self, node: BddPointer) -> BddPointer
pub(crate) fn high_link_of(&self, node: BddPointer) -> BddPointer
(internal) Get the high link of the node at a specified location.
sourcepub(crate) fn var_of(&self, node: BddPointer) -> BddVariable
pub(crate) fn var_of(&self, node: BddPointer) -> BddVariable
(internal) Get the conditioning variable of the node at a specified location.
Note that this also technically works for terminals, but the returned BddVariable
is
not valid in this Bdd
.
sourcepub(crate) fn mk_false(num_vars: u16) -> Bdd
pub(crate) fn mk_false(num_vars: u16) -> Bdd
(internal) Create a new Bdd
for the false
formula.
pub(crate) fn mk_var(num_vars: u16, var: BddVariable) -> Bdd
pub(crate) fn mk_not_var(num_vars: u16, var: BddVariable) -> Bdd
pub(crate) fn mk_literal(num_vars: u16, var: BddVariable, value: bool) -> Bdd
sourcepub(crate) fn push_node(&mut self, node: BddNode)
pub(crate) fn push_node(&mut self, node: BddNode)
(internal) Add a new node to an existing Bdd
, making the new node the root of the Bdd
.
sourcepub(crate) fn pointers(&self) -> Map<Range<usize>, fn(_: usize) -> BddPointer>
pub(crate) fn pointers(&self) -> Map<Range<usize>, fn(_: usize) -> BddPointer>
(internal) Create an iterator over all pointers of the Bdd
(including terminals!).
The iteration order is the same as the underlying representation, so you can expect terminals to be the first two nodes.
sourcepub(crate) fn nodes(&self) -> Iter<'_, BddNode>
pub(crate) fn nodes(&self) -> Iter<'_, BddNode>
(internal) Create an iterator over all nodes of the Bdd
(including terminals).
sourcepub fn is_valuation(&self) -> bool
pub fn is_valuation(&self) -> bool
Check if this Bdd
represents a single valuation with all variables fixed to a
specific value.
This can be used for example to verify that a set represented by a Bdd
is a singleton.
sourceimpl Bdd
impl Bdd
Utilities for extracting interesting valuations and paths from a Bdd
.
sourcepub fn first_valuation(&self) -> Option<BddValuation>
pub fn first_valuation(&self) -> Option<BddValuation>
Return the lexicographically first satisfying valuation of this Bdd
.
(In this context, lexicographically means 0 < 1
, with greatest variable id
being the most significant).
sourcepub fn last_valuation(&self) -> Option<BddValuation>
pub fn last_valuation(&self) -> Option<BddValuation>
Return the lexicographically last satisfying valuation of this Bdd
.
(In this context, lexicographically means 0 < 1
, with greatest variable id
being the most significant).
sourcepub fn first_clause(&self) -> Option<BddPartialValuation>
pub fn first_clause(&self) -> Option<BddPartialValuation>
Return the lexicographically fist path in this Bdd
, represented as
a conjunctive clause.
sourcepub fn last_clause(&self) -> Option<BddPartialValuation>
pub fn last_clause(&self) -> Option<BddPartialValuation>
Return the lexicographically last path in this Bdd
, represented as
a conjunctive clause.
sourcepub fn most_positive_valuation(&self) -> Option<BddValuation>
pub fn most_positive_valuation(&self) -> Option<BddValuation>
Return a valuation in this Bdd
that contains the greatest amount of positive literals.
If such valuation is not unique, the method should return the one that is first lexicographically.
sourcepub fn most_negative_valuation(&self) -> Option<BddValuation>
pub fn most_negative_valuation(&self) -> Option<BddValuation>
Return a valuation in this Bdd
that contains the greatest amount of negative literals.
If such valuation is not unique, the method should return the one that is first lexicographically.
sourcepub fn most_fixed_clause(&self) -> Option<BddPartialValuation>
pub fn most_fixed_clause(&self) -> Option<BddPartialValuation>
Compute the path in this Bdd
that has the highest amount of fixed variables.
If there are multiple such paths, try to order them lexicographically.
sourcepub fn most_free_clause(&self) -> Option<BddPartialValuation>
pub fn most_free_clause(&self) -> Option<BddPartialValuation>
Compute the path in this Bdd
that has the highest amount of free variables.
If there are multiple such paths, try to order them lexicographically.
sourcepub fn random_valuation<R: Rng>(&self, rng: &mut R) -> Option<BddValuation>
pub fn random_valuation<R: Rng>(&self, rng: &mut R) -> Option<BddValuation>
Pick a random valuation that satisfies this Bdd
, using a provided random number
generator.
Note that the random distribution with which the valuations are picked depends
on the structure of the Bdd
and is not necessarily uniform.
sourcepub fn random_clause<R: Rng>(&self, rng: &mut R) -> Option<BddPartialValuation>
pub fn random_clause<R: Rng>(&self, rng: &mut R) -> Option<BddPartialValuation>
Pick a random path that appears in this Bdd
, using a provided random number
generator.
Note that the distribution with which the path is picked depends on the structure
of the Bdd
and is not necessarily uniform.
sourceimpl Bdd
impl Bdd
Methods for working with Bdd
valuations.
sourcepub fn eval_in(&self, valuation: &BddValuation) -> bool
pub fn eval_in(&self, valuation: &BddValuation) -> bool
Evaluate this Bdd
in a specified BddValuation
.
sourceimpl Bdd
impl Bdd
sourcepub fn sat_valuations(&self) -> BddSatisfyingValuations<'_>ⓘNotable traits for BddSatisfyingValuations<'_>impl Iterator for BddSatisfyingValuations<'_> type Item = BddValuation;
pub fn sat_valuations(&self) -> BddSatisfyingValuations<'_>ⓘNotable traits for BddSatisfyingValuations<'_>impl Iterator for BddSatisfyingValuations<'_> type Item = BddValuation;
Create an iterator that goes through all the satisfying valuations of this Bdd
.
Note that the number of such valuations can be substantial and can be approximated
using Bdd.cardinality
.
sourcepub fn sat_clauses(&self) -> BddPathIterator<'_>ⓘNotable traits for BddPathIterator<'_>impl Iterator for BddPathIterator<'_> type Item = BddPartialValuation;
pub fn sat_clauses(&self) -> BddPathIterator<'_>ⓘNotable traits for BddPathIterator<'_>impl Iterator for BddPathIterator<'_> type Item = BddPartialValuation;
Create an iterator that goes through all paths of this Bdd
. Each path is represented
as a conjunctive clause in the form of BddPartialValuation
.
The whole formula represented by a Bdd
can be then seen as a disjunction of these
clauses/paths.
Trait Implementations
sourceimpl From<BddValuation> for Bdd
impl From<BddValuation> for Bdd
Convert a BddValuation to a Bdd with, well, exactly that one valuation.
sourcefn from(valuation: BddValuation) -> Self
fn from(valuation: BddValuation) -> Self
Performs the conversion.
impl Eq for Bdd
impl StructuralEq for Bdd
impl StructuralPartialEq for Bdd
Auto Trait Implementations
impl RefUnwindSafe for Bdd
impl Send for Bdd
impl Sync for Bdd
impl Unpin for Bdd
impl UnwindSafe for Bdd
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcepub fn borrow_mut(&mut self) -> &mut T
pub fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcepub fn to_owned(&self) -> T
pub fn to_owned(&self) -> T
Creates owned data from borrowed data, usually by cloning. Read more
sourcepub fn clone_into(&self, target: &mut T)
pub fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more