Skip to content

Commit a0e291f

Browse files
committed
P4: bonafide SddBuilder
This was the most destructive yet? Ran into problems with associated types and blanket generics (in particular, cannot have negative trait bounds, which makes it not possible to disambiguate which `BottomUpBuilder` impl to use; see rust-lang/rfcs#1053).
1 parent 6056b2f commit a0e291f

File tree

6 files changed

+621
-557
lines changed

6 files changed

+621
-557
lines changed

examples/bayesian_network_compiler.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::rsdd::builder::BottomUpBuilder;
66
use clap::Parser;
77
use rsdd::builder::cache::all_app::AllTable;
88
use rsdd::builder::decision_nnf_builder::DecisionNNFBuilder;
9-
use rsdd::builder::sdd_builder;
9+
use rsdd::builder::sdd_builder::{self, SddBuilder};
1010
use rsdd::repr::ddnnf::DDNNFPtr;
1111
use rsdd::repr::dtree::DTree;
1212
use rsdd::repr::robdd::BddPtr;

src/builder/bdd_builder.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl BddManagerStats {
8484
}
8585
}
8686

87-
pub trait BddBuilder<'a>: BottomUpBuilder<'a, Ptr = BddPtr<'a>> {
87+
pub trait BddBuilder<'a>: BottomUpBuilder<'a, BddPtr<'a>> {
8888
fn eq_bdd(&self, a: BddPtr, b: BddPtr) -> bool;
8989

9090
fn get_or_insert(&'a self, bdd: BddNode<'a>) -> BddPtr<'a>;
@@ -114,22 +114,22 @@ pub trait BddBuilder<'a>: BottomUpBuilder<'a, Ptr = BddPtr<'a>> {
114114
}
115115
}
116116

117-
impl<'a, T> BottomUpBuilder<'a> for T
117+
impl<'a, T> BottomUpBuilder<'a, BddPtr<'a>> for T
118118
where
119119
T: BddBuilder<'a>,
120120
{
121-
type Ptr = BddPtr<'a>;
121+
// type Ptr = BddPtr<'a>;
122122

123-
fn true_ptr(&self) -> Self::Ptr {
123+
fn true_ptr(&self) -> BddPtr<'a> {
124124
BddPtr::true_ptr()
125125
}
126126

127-
fn false_ptr(&self) -> Self::Ptr {
127+
fn false_ptr(&self) -> BddPtr<'a> {
128128
BddPtr::false_ptr()
129129
}
130130

131131
/// Get a pointer to the variable with label `lbl` and polarity `polarity`
132-
fn var(&'a self, label: VarLabel, polarity: bool) -> Self::Ptr {
132+
fn var(&'a self, label: VarLabel, polarity: bool) -> BddPtr<'a> {
133133
let bdd = BddNode::new(label, BddPtr::false_ptr(), BddPtr::true_ptr());
134134
let r = self.get_or_insert(bdd);
135135
if polarity {
@@ -153,45 +153,45 @@ where
153153
/// let a_and_not_a = man.and(a, a.neg());
154154
/// assert!(a_and_not_a.is_false());
155155
/// ```
156-
fn and(&'a self, f: Self::Ptr, g: Self::Ptr) -> Self::Ptr {
156+
fn and(&'a self, f: BddPtr<'a>, g: BddPtr<'a>) -> BddPtr<'a> {
157157
self.ite(f, g, BddPtr::false_ptr())
158158
}
159159

160-
fn negate(&'a self, f: Self::Ptr) -> Self::Ptr {
160+
fn negate(&'a self, f: BddPtr<'a>) -> BddPtr<'a> {
161161
f.neg()
162162
}
163163

164164
/// if f then g else h
165-
fn ite(&'a self, f: Self::Ptr, g: Self::Ptr, h: Self::Ptr) -> Self::Ptr {
165+
fn ite(&'a self, f: BddPtr<'a>, g: BddPtr<'a>, h: BddPtr<'a>) -> BddPtr<'a> {
166166
self.ite_helper(f, g, h)
167167
}
168168

169169
/// Compute the Boolean function `f iff g`
170-
fn iff(&'a self, f: Self::Ptr, g: Self::Ptr) -> Self::Ptr {
170+
fn iff(&'a self, f: BddPtr<'a>, g: BddPtr<'a>) -> BddPtr<'a> {
171171
self.ite(f, g, g.neg())
172172
}
173173

174-
fn xor(&'a self, f: Self::Ptr, g: Self::Ptr) -> Self::Ptr {
174+
fn xor(&'a self, f: BddPtr<'a>, g: BddPtr<'a>) -> BddPtr<'a> {
175175
self.ite(f, g.neg(), g)
176176
}
177177

178178
/// Existentially quantifies out the variable `lbl` from `f`
179-
fn exists(&'a self, bdd: Self::Ptr, lbl: VarLabel) -> Self::Ptr {
179+
fn exists(&'a self, bdd: BddPtr<'a>, lbl: VarLabel) -> BddPtr<'a> {
180180
// TODO this can be optimized by specializing it
181181
let v1 = self.condition(bdd, lbl, true);
182182
let v2 = self.condition(bdd, lbl, false);
183183
self.or(v1, v2)
184184
}
185185

186186
/// Compute the Boolean function `f | var = value`
187-
fn condition(&'a self, bdd: Self::Ptr, lbl: VarLabel, value: bool) -> Self::Ptr {
187+
fn condition(&'a self, bdd: BddPtr<'a>, lbl: VarLabel, value: bool) -> BddPtr<'a> {
188188
let r = self.cond_helper(bdd, lbl, value);
189189
bdd.clear_scratch();
190190
r
191191
}
192192

193193
/// Compose `g` into `f` by substituting for `lbl`
194-
fn compose(&'a self, f: Self::Ptr, lbl: VarLabel, g: Self::Ptr) -> Self::Ptr {
194+
fn compose(&'a self, f: BddPtr<'a>, lbl: VarLabel, g: BddPtr<'a>) -> BddPtr<'a> {
195195
// TODO this can be optimized with a specialized implementation to make
196196
// it a single traversal
197197
let var = self.var(lbl, true);

src/builder/mod.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,41 @@ pub mod bdd_plan;
1010
pub mod decision_nnf_builder;
1111
pub mod sdd_builder;
1212

13-
pub trait BottomUpBuilder<'a> {
14-
type Ptr;
13+
pub trait BottomUpBuilder<'a, Ptr> {
14+
// type Ptr;
1515

1616
// constants --- can elide the input lifetimes
17-
fn true_ptr(&self) -> Self::Ptr;
18-
fn false_ptr(&self) -> Self::Ptr;
17+
fn true_ptr(&self) -> Ptr;
18+
fn false_ptr(&self) -> Ptr;
1919

20-
fn var(&'a self, label: VarLabel, polarity: bool) -> Self::Ptr;
20+
fn var(&'a self, label: VarLabel, polarity: bool) -> Ptr;
2121

2222
// primitive operations
23-
fn and(&'a self, a: Self::Ptr, b: Self::Ptr) -> Self::Ptr;
23+
fn and(&'a self, a: Ptr, b: Ptr) -> Ptr;
2424

2525
/// Compute the Boolean function `f || g`
2626
/// by default, or is defined using de morgan's law as and
27-
fn or(&'a self, a: Self::Ptr, b: Self::Ptr) -> Self::Ptr {
27+
fn or(&'a self, a: Ptr, b: Ptr) -> Ptr {
2828
self.negate(self.and(self.negate(a), self.negate(b)))
2929
}
30-
fn negate(&'a self, f: Self::Ptr) -> Self::Ptr;
30+
fn negate(&'a self, f: Ptr) -> Ptr;
3131

3232
/// if f then g else h
33-
fn ite(&'a self, f: Self::Ptr, g: Self::Ptr, h: Self::Ptr) -> Self::Ptr;
33+
fn ite(&'a self, f: Ptr, g: Ptr, h: Ptr) -> Ptr;
3434

3535
/// if and only if (i.e., Boolean equality)
36-
fn iff(&'a self, a: Self::Ptr, b: Self::Ptr) -> Self::Ptr;
36+
fn iff(&'a self, a: Ptr, b: Ptr) -> Ptr;
3737

3838
/// logical exclusive-or
39-
fn xor(&'a self, a: Self::Ptr, b: Self::Ptr) -> Self::Ptr;
39+
fn xor(&'a self, a: Ptr, b: Ptr) -> Ptr;
4040

4141
/// existentially quantifies `v` out of `f`
42-
fn exists(&'a self, f: Self::Ptr, v: VarLabel) -> Self::Ptr;
42+
fn exists(&'a self, f: Ptr, v: VarLabel) -> Ptr;
4343

4444
/// conditions f | v = value
45-
fn condition(&'a self, a: Self::Ptr, v: VarLabel, value: bool) -> Self::Ptr;
45+
fn condition(&'a self, a: Ptr, v: VarLabel, value: bool) -> Ptr;
4646

4747
/// compose g into f for variable v
4848
/// I.e., computes the logical function (exists v. (g <=> v) /\ f).
49-
fn compose(&'a self, f: Self::Ptr, lbl: VarLabel, g: Self::Ptr) -> Self::Ptr;
49+
fn compose(&'a self, f: Ptr, lbl: VarLabel, g: Ptr) -> Ptr;
5050
}

0 commit comments

Comments
 (0)