fn main() -> std::io::Result<()> {
env_logger::init();
let mut ctx = easy_smt::ContextBuilder::new().with_z3_defaults().build()?;
ctx.declare_sort("MySet", 0)?;
ctx.declare_sort("MyElement", 0)?;
ctx.declare_fun("empty", vec![ctx.atom("MySet")], ctx.bool_sort())?;
ctx.declare_fun(
"member",
vec![ctx.atom("MyElement"), ctx.atom("MySet")],
ctx.bool_sort(),
)?;
ctx.declare_fun(
"subset",
vec![ctx.atom("MySet"), ctx.atom("MySet")],
ctx.bool_sort(),
)?;
ctx.assert(
ctx.forall(
[("s1", ctx.atom("MySet")), ("s2", ctx.atom("MySet"))],
ctx.or(
ctx.list(vec![ctx.atom("subset"), ctx.atom("s1"), ctx.atom("s2")]),
ctx.exists(
[("x", ctx.atom("MyElement"))],
ctx.and(
ctx.list(vec![ctx.atom("member"), ctx.atom("x"), ctx.atom("s1")]),
ctx.not(ctx.list(vec![ctx.atom("member"), ctx.atom("x"), ctx.atom("s2")])),
),
),
),
),
)?;
ctx.assert(
ctx.forall(
[("s1", ctx.atom("MySet"))],
ctx.eq(
ctx.not(ctx.list(vec![ctx.atom("empty"), ctx.atom("s1")])),
ctx.exists(
[("x", ctx.atom("MyElement"))],
ctx.list(vec![ctx.atom("member"), ctx.atom("x"), ctx.atom("s1")]),
),
),
),
)?;
ctx.declare_const("s1", ctx.atom("MySet"))?;
ctx.declare_const("s2", ctx.atom("MySet"))?;
ctx.assert(ctx.list(vec![ctx.atom("empty"), ctx.atom("s1")]))?;
ctx.assert(ctx.not(ctx.list(vec![ctx.atom("subset"), ctx.atom("s1"), ctx.atom("s2")])))?;
match ctx.check()? {
easy_smt::Response::Sat => {
println!("Solver returned SAT. This is unexpected!");
}
easy_smt::Response::Unsat => {
println!("Solver returned UNSAT. This is expected.");
}
easy_smt::Response::Unknown => {
println!("Solver returned UNKNOWN. This is unexpected!");
}
}
Ok(())
}