blob: f29a7132e831b3f0e926968ce0d4fc6d843200fe [file] [log] [blame]
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(non_snake_case)]
extern crate test;
use self::test::Bencher;
use unify::{UnifyKey, UnificationTable};
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
struct UnitKey(u32);
impl UnifyKey for UnitKey {
type Value = ();
fn index(&self) -> u32 {
self.0
}
fn from_index(u: u32) -> UnitKey {
UnitKey(u)
}
fn tag(_: Option<UnitKey>) -> &'static str {
"UnitKey"
}
}
#[test]
fn basic() {
let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
let k1 = ut.new_key(());
let k2 = ut.new_key(());
assert_eq!(ut.unioned(k1, k2), false);
ut.union(k1, k2);
assert_eq!(ut.unioned(k1, k2), true);
}
#[test]
fn big_array() {
let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
let mut keys = Vec::new();
const MAX: usize = 1 << 15;
for _ in 0..MAX {
keys.push(ut.new_key(()));
}
for i in 1..MAX {
let l = keys[i - 1];
let r = keys[i];
ut.union(l, r);
}
for i in 0..MAX {
assert!(ut.unioned(keys[0], keys[i]));
}
}
#[bench]
fn big_array_bench(b: &mut Bencher) {
let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
let mut keys = Vec::new();
const MAX: usize = 1 << 15;
for _ in 0..MAX {
keys.push(ut.new_key(()));
}
b.iter(|| {
for i in 1..MAX {
let l = keys[i - 1];
let r = keys[i];
ut.union(l, r);
}
for i in 0..MAX {
assert!(ut.unioned(keys[0], keys[i]));
}
})
}
#[test]
fn even_odd() {
let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
let mut keys = Vec::new();
const MAX: usize = 1 << 10;
for i in 0..MAX {
let key = ut.new_key(());
keys.push(key);
if i >= 2 {
ut.union(key, keys[i - 2]);
}
}
for i in 1..MAX {
assert!(!ut.unioned(keys[i - 1], keys[i]));
}
for i in 2..MAX {
assert!(ut.unioned(keys[i - 2], keys[i]));
}
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
struct IntKey(u32);
impl UnifyKey for IntKey {
type Value = Option<i32>;
fn index(&self) -> u32 {
self.0
}
fn from_index(u: u32) -> IntKey {
IntKey(u)
}
fn tag(_: Option<IntKey>) -> &'static str {
"IntKey"
}
}
/// Test unifying a key whose value is `Some(_)` with a key whose value is `None`.
/// Afterwards both should be `Some(_)`.
#[test]
fn unify_key_Some_key_None() {
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
let k1 = ut.new_key(Some(22));
let k2 = ut.new_key(None);
assert!(ut.unify_var_var(k1, k2).is_ok());
assert_eq!(ut.probe(k2), Some(22));
assert_eq!(ut.probe(k1), Some(22));
}
/// Test unifying a key whose value is `None` with a key whose value is `Some(_)`.
/// Afterwards both should be `Some(_)`.
#[test]
fn unify_key_None_key_Some() {
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
let k1 = ut.new_key(Some(22));
let k2 = ut.new_key(None);
assert!(ut.unify_var_var(k2, k1).is_ok());
assert_eq!(ut.probe(k2), Some(22));
assert_eq!(ut.probe(k1), Some(22));
}
/// Test unifying a key whose value is `Some(x)` with a key whose value is `Some(y)`.
/// This should yield an error.
#[test]
fn unify_key_Some_x_key_Some_y() {
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
let k1 = ut.new_key(Some(22));
let k2 = ut.new_key(Some(23));
assert_eq!(ut.unify_var_var(k1, k2), Err((22, 23)));
assert_eq!(ut.unify_var_var(k2, k1), Err((23, 22)));
assert_eq!(ut.probe(k1), Some(22));
assert_eq!(ut.probe(k2), Some(23));
}
/// Test unifying a key whose value is `Some(x)` with a key whose value is `Some(x)`.
/// This should be ok.
#[test]
fn unify_key_Some_x_key_Some_x() {
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
let k1 = ut.new_key(Some(22));
let k2 = ut.new_key(Some(22));
assert!(ut.unify_var_var(k1, k2).is_ok());
assert_eq!(ut.probe(k1), Some(22));
assert_eq!(ut.probe(k2), Some(22));
}
/// Test unifying a key whose value is `None` with a value is `x`.
/// Afterwards key should be `x`.
#[test]
fn unify_key_None_val() {
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
let k1 = ut.new_key(None);
assert!(ut.unify_var_value(k1, 22).is_ok());
assert_eq!(ut.probe(k1), Some(22));
}
/// Test unifying a key whose value is `Some(x)` with the value `y`.
/// This should yield an error.
#[test]
fn unify_key_Some_x_val_y() {
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
let k1 = ut.new_key(Some(22));
assert_eq!(ut.unify_var_value(k1, 23), Err((22, 23)));
assert_eq!(ut.probe(k1), Some(22));
}
/// Test unifying a key whose value is `Some(x)` with the value `x`.
/// This should be ok.
#[test]
fn unify_key_Some_x_val_x() {
let mut ut: UnificationTable<IntKey> = UnificationTable::new();
let k1 = ut.new_key(Some(22));
assert!(ut.unify_var_value(k1, 22).is_ok());
assert_eq!(ut.probe(k1), Some(22));
}