use z3::ast;
use z3::datatype_builder::DatatypeAccessor;
use z3::*;
#[test]
fn test_datatype_accessor_constructors() {
let _ = env_logger::try_init();
let as_sort = DatatypeAccessor::sort(Sort::int());
match as_sort {
DatatypeAccessor::Sort(s) => {
assert_eq!(s, Sort::int());
}
_ => panic!("Expected DatatypeAccessor::Sort variant"),
}
let as_datatype = DatatypeAccessor::datatype("SomeType");
match as_datatype {
DatatypeAccessor::Datatype(sym) => {
assert_eq!(sym, "SomeType".into());
}
_ => panic!("Expected DatatypeAccessor::Datatype variant"),
}
}
#[test]
fn test_create_datatypes_with_explicit_accessors_and_constructors() {
let _ = env_logger::try_init();
let tree_builder = DatatypeBuilder::new("TreeX")
.variant("leaf", vec![("val", DatatypeAccessor::sort(Sort::int()))])
.variant(
"node",
vec![("children", DatatypeAccessor::datatype("ListX"))],
);
let list_builder = DatatypeBuilder::new("ListX")
.variant("nil", vec![])
.variant(
"cons",
vec![
("car", DatatypeAccessor::datatype("TreeX")),
("cdr", DatatypeAccessor::datatype("ListX")),
],
);
let sorts = z3::datatype_builder::create_datatypes(vec![tree_builder, list_builder]);
assert_eq!(sorts.len(), 2);
let tree_sort = &sorts[0];
let list_sort = &sorts[1];
assert_eq!(tree_sort.variants.len(), 2);
assert_eq!(tree_sort.variants[0].accessors.len(), 1); assert_eq!(tree_sort.variants[1].accessors.len(), 1);
assert_eq!(list_sort.variants.len(), 2);
assert_eq!(list_sort.variants[0].accessors.len(), 0); assert_eq!(list_sort.variants[1].accessors.len(), 2);
let solver = Solver::new();
let ten = ast::Int::from_i64(10);
let twenty = ast::Int::from_i64(20);
let leaf_ten = tree_sort.variants[0].constructor.apply(&[&ten]);
let leaf_twenty = tree_sort.variants[0].constructor.apply(&[&twenty]);
let nil = list_sort.variants[0].constructor.apply(&[]);
let cons_twenty_nil = list_sort.variants[1]
.constructor
.apply(&[&leaf_twenty, &nil]);
let cons_ten_cons_twenty_nil = list_sort.variants[1]
.constructor
.apply(&[&leaf_ten, &cons_twenty_nil]);
let node = tree_sort.variants[1]
.constructor
.apply(&[&cons_ten_cons_twenty_nil]);
let children = tree_sort.variants[1].accessors[0].apply(&[&node]);
solver.assert(children.eq(&cons_ten_cons_twenty_nil));
let first = list_sort.variants[1].accessors[0].apply(&[&cons_ten_cons_twenty_nil]);
solver.assert(first.eq(&leaf_ten));
let val_from_leaf = tree_sort.variants[0].accessors[0]
.apply(&[&leaf_ten])
.as_int()
.unwrap();
solver.assert(val_from_leaf.eq(&ten));
assert_eq!(solver.check(), SatResult::Sat);
}
#[test]
#[should_panic(expected = "At least one DatatypeBuilder must be specified")]
fn test_create_datatypes_empty_should_panic() {
let _ = env_logger::try_init();
let _ = z3::datatype_builder::create_datatypes(vec![]);
}