lib-laddertypes/src/test/unification.rs

193 lines
5.3 KiB
Rust
Raw Normal View History

2023-10-31 16:26:54 +01:00
use {
2025-02-04 14:34:55 +01:00
crate::{dict::*, parser::*, unparser::*, term::*, unification::*},
2023-10-31 16:26:54 +01:00
std::iter::FromIterator
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
fn test_unify(ts1: &str, ts2: &str, expect_unificator: bool) {
2025-02-04 14:34:55 +01:00
let mut dict = BimapTypeDict::new();
2023-10-31 16:26:54 +01:00
dict.add_varname(String::from("T"));
dict.add_varname(String::from("U"));
dict.add_varname(String::from("V"));
dict.add_varname(String::from("W"));
let mut t1 = dict.parse(ts1).unwrap();
let mut t2 = dict.parse(ts2).unwrap();
let σ = crate::unify( &t1, &t2 );
if expect_unificator {
assert!(σ.is_ok());
let σ = σ.unwrap();
assert_eq!(
t1.apply_substitution(&|v| σ.get(v).cloned()),
t2.apply_substitution(&|v| σ.get(v).cloned())
);
} else {
assert!(! σ.is_ok());
}
}
#[test]
fn test_unification_error() {
2025-02-04 14:34:55 +01:00
let mut dict = BimapTypeDict::new();
2023-10-31 16:26:54 +01:00
dict.add_varname(String::from("T"));
assert_eq!(
crate::unify(
&dict.parse("<A T>").unwrap(),
&dict.parse("<B T>").unwrap()
),
Err(UnificationError {
addr: vec![0],
t1: dict.parse("A").unwrap(),
t2: dict.parse("B").unwrap()
})
);
assert_eq!(
crate::unify(
&dict.parse("<V <U A> T>").unwrap(),
&dict.parse("<V <U B> T>").unwrap()
),
Err(UnificationError {
addr: vec![1, 1],
t1: dict.parse("A").unwrap(),
t2: dict.parse("B").unwrap()
})
);
assert_eq!(
crate::unify(
&dict.parse("T").unwrap(),
&dict.parse("<Seq T>").unwrap()
),
Err(UnificationError {
addr: vec![],
t1: dict.parse("T").unwrap(),
t2: dict.parse("<Seq T>").unwrap()
})
);
2023-10-31 16:26:54 +01:00
}
#[test]
fn test_unification() {
test_unify("A", "A", true);
test_unify("A", "B", false);
test_unify("<Seq T>", "<Seq Ascii~Char>", true);
test_unify("<Seq T>", "<U Char>", true);
test_unify(
"<Seq Path~<Seq Char>>~<SepSeq Char '\n'>~<Seq Char>",
"<Seq T~<Seq Char>>~<SepSeq Char '\n'>~<Seq Char>",
true
);
2023-11-11 16:26:30 +01:00
2025-02-04 14:34:55 +01:00
let mut dict = BimapTypeDict::new();
2023-11-11 16:26:30 +01:00
dict.add_varname(String::from("T"));
dict.add_varname(String::from("U"));
dict.add_varname(String::from("V"));
dict.add_varname(String::from("W"));
assert_eq!(
UnificationProblem::new(vec![
(dict.parse("U").unwrap(), dict.parse("<Seq Char>").unwrap()),
(dict.parse("T").unwrap(), dict.parse("<Seq U>").unwrap()),
]).solve(),
Ok(
vec![
// T
(TypeID::Var(0), dict.parse("<Seq <Seq Char>>").unwrap()),
// U
(TypeID::Var(1), dict.parse("<Seq Char>").unwrap())
].into_iter().collect()
)
);
assert_eq!(
UnificationProblem::new(vec![
(dict.parse("<Seq T>").unwrap(), dict.parse("<Seq W~<Seq Char>>").unwrap()),
(dict.parse("<Seq >").unwrap(), dict.parse("<Seq W>").unwrap()),
]).solve(),
Ok(
vec![
// W
(TypeID::Var(3), dict.parse("").unwrap()),
// T
(TypeID::Var(0), dict.parse("~<Seq Char>").unwrap())
].into_iter().collect()
)
);
2023-10-31 16:26:54 +01:00
}
2025-02-09 16:58:58 +01:00
#[test]
fn test_subtype_unification() {
2025-02-04 14:34:55 +01:00
let mut dict = BimapTypeDict::new();
2025-02-09 16:58:58 +01:00
dict.add_varname(String::from("T"));
dict.add_varname(String::from("U"));
dict.add_varname(String::from("V"));
dict.add_varname(String::from("W"));
assert_eq!(
UnificationProblem::new(vec![
(dict.parse("<Seq~T <Digit 10> ~ Char>").unwrap(),
dict.parse("<Seq~<LengthPrefix x86.UInt64> Char ~ Ascii>").unwrap()),
]).solve_subtype(),
Ok((
dict.parse("<Seq <Digit 10>>").unwrap(),
2025-02-09 16:58:58 +01:00
vec![
// T
(TypeID::Var(0), dict.parse("<LengthPrefix x86.UInt64>").unwrap())
].into_iter().collect()
))
2025-02-09 16:58:58 +01:00
);
assert_eq!(
UnificationProblem::new(vec![
(dict.parse("U").unwrap(), dict.parse("<Seq Char>").unwrap()),
(dict.parse("T").unwrap(), dict.parse("<Seq U>").unwrap()),
]).solve_subtype(),
Ok((
TypeTerm::unit(),
2025-02-09 16:58:58 +01:00
vec![
// T
(TypeID::Var(0), dict.parse("<Seq <Seq Char>>").unwrap()),
// U
(TypeID::Var(1), dict.parse("<Seq Char>").unwrap())
].into_iter().collect()
))
2025-02-09 16:58:58 +01:00
);
assert_eq!(
UnificationProblem::new(vec![
(dict.parse("<Seq T>").unwrap(),
dict.parse("<Seq W~<Seq Char>>").unwrap()),
2025-02-25 22:57:50 +01:00
(dict.parse("<Seq~<LengthPrefix x86.UInt64> ~<PosInt 10 BigEndian>>").unwrap(),
dict.parse("<<LengthPrefix x86.UInt64> W>").unwrap()),
2025-02-09 16:58:58 +01:00
]).solve_subtype(),
Ok((
dict.parse("
2025-02-25 22:57:50 +01:00
<Seq ~<PosInt 10 BigEndian>>
").unwrap(),
2025-02-09 16:58:58 +01:00
vec![
// W
(TypeID::Var(3), dict.parse("~<PosInt 10 BigEndian>").unwrap()),
// T
(TypeID::Var(0), dict.parse("~<PosInt 10 BigEndian>~<Seq Char>").unwrap())
].into_iter().collect()
))
2025-02-09 16:58:58 +01:00
);
}