use crate::Context;
use crate::ast::Ast;
use std::ffi::CString;
use z3_sys::*;
pub struct Regexp {
pub(crate) ctx: Context,
pub(crate) z3_ast: Z3_ast,
}
impl Regexp {
pub fn literal(s: &str) -> Self {
let ctx = &Context::thread_local();
unsafe {
Self::wrap(ctx, {
let c_str = CString::new(s).unwrap();
Z3_mk_seq_to_re(
ctx.z3_ctx.0,
Z3_mk_string(ctx.z3_ctx.0, c_str.as_ptr()).unwrap(),
)
.unwrap()
})
}
}
pub fn range(lo: &char, hi: &char) -> Self {
let ctx = &Context::thread_local();
unsafe {
Self::wrap(ctx, {
let lo_cs = CString::new(lo.to_string()).unwrap();
let hi_cs = CString::new(hi.to_string()).unwrap();
let lo_z3s = Z3_mk_string(ctx.z3_ctx.0, lo_cs.as_ptr()).unwrap();
Z3_inc_ref(ctx.z3_ctx.0, lo_z3s);
let hi_z3s = Z3_mk_string(ctx.z3_ctx.0, hi_cs.as_ptr()).unwrap();
Z3_inc_ref(ctx.z3_ctx.0, hi_z3s);
let ret = Z3_mk_re_range(ctx.z3_ctx.0, lo_z3s, hi_z3s);
Z3_dec_ref(ctx.z3_ctx.0, lo_z3s);
Z3_dec_ref(ctx.z3_ctx.0, hi_z3s);
ret.unwrap()
})
}
}
pub fn r#loop(&self, lo: u32, hi: u32) -> Self {
unsafe {
Self::wrap(&self.ctx, {
Z3_mk_re_loop(self.ctx.z3_ctx.0, self.z3_ast, lo, hi).unwrap()
})
}
}
pub fn power(&self, n: u32) -> Self {
unsafe {
Self::wrap(&self.ctx, {
Z3_mk_re_power(self.ctx.z3_ctx.0, self.z3_ast, n).unwrap()
})
}
}
pub fn full() -> Self {
let ctx = &Context::thread_local();
unsafe {
Self::wrap(ctx, {
Z3_mk_re_full(
ctx.z3_ctx.0,
Z3_mk_re_sort(ctx.z3_ctx.0, Z3_mk_string_sort(ctx.z3_ctx.0).unwrap()).unwrap(),
)
.unwrap()
})
}
}
pub fn allchar() -> Self {
let ctx = &Context::thread_local();
unsafe {
Self::wrap(ctx, {
Z3_mk_re_allchar(
ctx.z3_ctx.0,
Z3_mk_re_sort(ctx.z3_ctx.0, Z3_mk_string_sort(ctx.z3_ctx.0).unwrap()).unwrap(),
)
.unwrap()
})
}
}
pub fn empty() -> Self {
let ctx = &Context::thread_local();
unsafe {
Self::wrap(ctx, {
Z3_mk_re_empty(
ctx.z3_ctx.0,
Z3_mk_re_sort(ctx.z3_ctx.0, Z3_mk_string_sort(ctx.z3_ctx.0).unwrap()).unwrap(),
)
.unwrap()
})
}
}
crate::ast::unop! {
plus(Z3_mk_re_plus, Self);
star(Z3_mk_re_star, Self);
complement(Z3_mk_re_complement, Self);
option(Z3_mk_re_option, Self);
}
crate::ast::binop! {
diff(Z3_mk_re_diff, Self);
}
crate::ast::varop! {
concat(Z3_mk_re_concat, Self);
union(Z3_mk_re_union, Self);
intersect(Z3_mk_re_intersect, Self);
}
}