eqlog-runtime 0.9.0

Datalog with equality
Documentation
use std::collections::BTreeMap;
use std::fmt;

#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct Unification<T> {
    parents: Vec<T>,
    sizes: Vec<u32>,
}

impl<T: Copy + PartialEq + From<u32> + Into<u32>> Unification<T> {
    pub fn new() -> Self {
        Unification {
            parents: Vec::new(),
            sizes: Vec::new(),
        }
    }
    pub fn root(&mut self, mut el: T) -> T {
        let mut parent = self.parents[el.into() as usize];
        while el != parent {
            self.parents[el.into() as usize] = self.parents[parent.into() as usize];
            el = parent;
            parent = self.parents[parent.into() as usize];
        }
        el
    }
    pub fn root_const(&self, mut el: T) -> T {
        let mut parent = self.parents[el.into() as usize];
        while el != parent {
            el = parent;
            parent = self.parents[el.into() as usize];
        }
        el
    }
    pub fn union_roots_into(&mut self, lhs: T, rhs: T) {
        assert!(lhs == self.root(lhs));
        assert!(rhs == self.root(rhs));
        self.parents[lhs.into() as usize] = rhs;
    }
    pub fn increase_size_to(&mut self, new_size: usize) {
        assert!(new_size >= self.len());
        assert!((u32::MAX as usize) > new_size);
        for i in self.len()..new_size {
            self.parents.push(T::from(i as u32));
        }
    }
    pub fn len(&self) -> usize {
        self.parents.len()
    }
}

impl<T: Copy + PartialEq + From<u32> + Into<u32> + PartialOrd + Ord> Unification<T> {
    pub fn classes(&self) -> BTreeMap<T, Vec<T>> {
        let mut result = BTreeMap::new();
        for p in 0..self.parents.len() {
            let p = T::from(p as u32);
            let root = self.root_const(p);

            // TODO: Eliminate one search once try_insert is stabilized.
            if !result.contains_key(&root) {
                result.insert(root, Vec::new());
            }
            let class_els = result.get_mut(&root).unwrap();

            if p != root {
                class_els.push(p);
            }
        }
        result
    }
}

impl<T: Copy + PartialEq + From<u32> + Into<u32> + PartialOrd + Ord + fmt::Display> Unification<T> {}