use std::mem;
#[derive(Clone)]
-pub struct TransitiveRelation<T:Debug+PartialEq> {
+pub struct TransitiveRelation<T: Debug + PartialEq> {
// List of elements. This is used to map from a T to a usize. We
// expect domain to be small so just use a linear list versus a
// hashmap or something.
// are added with new elements. Perhaps better would be to ask the
// user for a batch of edges to minimize this effect, but I
// already wrote the code this way. :P -nmatsakis
- closure: RefCell<Option<BitMatrix>>
+ closure: RefCell<Option<BitMatrix>>,
}
#[derive(Clone, PartialEq, PartialOrd)]
target: Index,
}
-impl<T:Debug+PartialEq> TransitiveRelation<T> {
+impl<T: Debug + PartialEq> TransitiveRelation<T> {
pub fn new() -> TransitiveRelation<T> {
- TransitiveRelation { elements: vec![],
- edges: vec![],
- closure: RefCell::new(None) }
+ TransitiveRelation {
+ elements: vec![],
+ edges: vec![],
+ closure: RefCell::new(None),
+ }
}
fn index(&self, a: &T) -> Option<Index> {
pub fn add(&mut self, a: T, b: T) {
let a = self.add_index(a);
let b = self.add_index(b);
- let edge = Edge { source: a, target: b };
+ let edge = Edge {
+ source: a,
+ target: b,
+ };
if !self.edges.contains(&edge) {
self.edges.push(edge);
/// Check whether `a < target` (transitively)
pub fn contains(&self, a: &T, b: &T) -> bool {
match (self.index(a), self.index(b)) {
- (Some(a), Some(b)) =>
- self.with_closure(|closure| closure.contains(a.0, b.0)),
- (None, _) | (_, None) =>
- false,
+ (Some(a), Some(b)) => self.with_closure(|closure| closure.contains(a.0, b.0)),
+ (None, _) | (_, None) => false,
}
}
pub fn minimal_upper_bounds(&self, a: &T, b: &T) -> Vec<&T> {
let (mut a, mut b) = match (self.index(a), self.index(b)) {
(Some(a), Some(b)) => (a, b),
- (None, _) | (_, None) => { return vec![]; }
+ (None, _) | (_, None) => {
+ return vec![];
+ }
};
// in some cases, there are some arbitrary choices to be made;
.collect()
}
- fn with_closure<OP,R>(&self, op: OP) -> R
+ fn with_closure<OP, R>(&self, op: OP) -> R
where OP: FnOnce(&BitMatrix) -> R
{
let mut closure_cell = self.closure.borrow_mut();
// b -> b1 ---+
let mut relation = TransitiveRelation::new();
- relation.add("a", "a1");
- relation.add("a", "b1");
- relation.add("b", "a1");
- relation.add("b", "b1");
+ relation.add("a", "a1");
+ relation.add("a", "b1");
+ relation.add("b", "a1");
+ relation.add("b", "b1");
relation.add("a1", "x");
relation.add("b1", "x");
- assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"a1", &"b1"]);
+ assert_eq!(relation.minimal_upper_bounds(&"a", &"b"),
+ vec![&"a1", &"b1"]);
assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x"));
}
// b -> b1 -> b2 ---------+
let mut relation = TransitiveRelation::new();
- relation.add("a", "a1");
- relation.add("a", "b1");
- relation.add("b", "a1");
- relation.add("b", "b1");
+ relation.add("a", "a1");
+ relation.add("a", "b1");
+ relation.add("b", "a1");
+ relation.add("b", "b1");
- relation.add("a1", "a2");
- relation.add("a1", "b2");
- relation.add("b1", "a2");
- relation.add("b1", "b2");
+ relation.add("a1", "a2");
+ relation.add("a1", "b2");
+ relation.add("b1", "a2");
+ relation.add("b1", "b2");
relation.add("a2", "a3");
relation.add("a3", "x");
relation.add("b2", "x");
- assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"a1", &"b1"]);
- assert_eq!(relation.minimal_upper_bounds(&"a1", &"b1"), vec![&"a2", &"b2"]);
+ assert_eq!(relation.minimal_upper_bounds(&"a", &"b"),
+ vec![&"a1", &"b1"]);
+ assert_eq!(relation.minimal_upper_bounds(&"a1", &"b1"),
+ vec![&"a2", &"b2"]);
assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x"));
}
// b -> b1 ---+
let mut relation = TransitiveRelation::new();
- relation.add("a", "a1");
- relation.add("b", "b1");
+ relation.add("a", "a1");
+ relation.add("b", "b1");
relation.add("a1", "x");
relation.add("b1", "x");
// "digraph { a -> c -> d; b -> d; }",
let mut relation = TransitiveRelation::new();
- relation.add("a", "c");
- relation.add("c", "d");
- relation.add("b", "d");
+ relation.add("a", "c");
+ relation.add("c", "d");
+ relation.add("b", "d");
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"d"]);
}
// "digraph { a -> c -> d; d -> c; a -> d; b -> d; }",
let mut relation = TransitiveRelation::new();
- relation.add("a", "c");
- relation.add("c", "d");
- relation.add("d", "c");
- relation.add("a", "d");
- relation.add("b", "d");
+ relation.add("a", "c");
+ relation.add("c", "d");
+ relation.add("d", "c");
+ relation.add("a", "d");
+ relation.add("b", "d");
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]);
}
// "digraph { a -> c -> d; d -> c; b -> d; b -> c; }",
let mut relation = TransitiveRelation::new();
- relation.add("a", "c");
- relation.add("c", "d");
- relation.add("d", "c");
- relation.add("b", "d");
- relation.add("b", "c");
+ relation.add("a", "c");
+ relation.add("c", "d");
+ relation.add("d", "c");
+ relation.add("b", "d");
+ relation.add("b", "c");
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]);
}
// "digraph { a -> c -> d -> e -> c; b -> d; b -> e; }",
let mut relation = TransitiveRelation::new();
- relation.add("a", "c");
- relation.add("c", "d");
- relation.add("d", "e");
- relation.add("e", "c");
- relation.add("b", "d");
- relation.add("b", "e");
+ relation.add("a", "c");
+ relation.add("c", "d");
+ relation.add("d", "e");
+ relation.add("e", "c");
+ relation.add("b", "d");
+ relation.add("b", "e");
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]);
}
// "digraph { a -> c -> d -> e -> c; a -> d; b -> e; }"
let mut relation = TransitiveRelation::new();
- relation.add("a", "c");
- relation.add("c", "d");
- relation.add("d", "e");
- relation.add("e", "c");
- relation.add("a", "d");
- relation.add("b", "e");
+ relation.add("a", "c");
+ relation.add("c", "d");
+ relation.add("d", "e");
+ relation.add("e", "c");
+ relation.add("a", "d");
+ relation.add("b", "e");
assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"c"]);
}