1use std::fmt;
2use z3_sys::*;
3
4use crate::{
5 AstVector, Context, FuncEntry, FuncInterp,
6 ast::{Ast, Dynamic},
7};
8
9impl FuncInterp {
10 pub(crate) unsafe fn wrap(ctx: &Context, z3_func_interp: Z3_func_interp) -> Self {
11 unsafe {
12 Z3_func_interp_inc_ref(ctx.z3_ctx.0, z3_func_interp);
13 }
14
15 Self {
16 ctx: ctx.clone(),
17 z3_func_interp,
18 }
19 }
20
21 pub fn get_arity(&self) -> usize {
23 unsafe { Z3_func_interp_get_arity(self.ctx.z3_ctx.0, self.z3_func_interp) as usize }
24 }
25
26 pub fn get_num_entries(&self) -> u32 {
28 unsafe { Z3_func_interp_get_num_entries(self.ctx.z3_ctx.0, self.z3_func_interp) }
29 }
30
31 pub fn add_entry(&self, args: &[Dynamic], value: &Dynamic) {
33 let v: AstVector = args.into();
34 unsafe {
35 Z3_func_interp_add_entry(
36 self.ctx.z3_ctx.0,
37 self.z3_func_interp,
38 v.z3_ast_vector,
39 value.z3_ast,
40 );
41 }
42 }
43
44 pub fn get_entries(&self) -> Vec<FuncEntry> {
46 (0..self.get_num_entries())
47 .map(|i| unsafe {
48 FuncEntry::wrap(
49 &self.ctx,
50 Z3_func_interp_get_entry(self.ctx.z3_ctx.0, self.z3_func_interp, i).unwrap(),
51 )
52 })
53 .collect()
54 }
55
56 pub fn get_else(&self) -> Dynamic {
59 unsafe {
60 Dynamic::wrap(
61 &self.ctx,
62 Z3_func_interp_get_else(self.ctx.z3_ctx.0, self.z3_func_interp).unwrap(),
63 )
64 }
65 }
66
67 pub fn set_else(&self, ast: &Dynamic) {
69 unsafe { Z3_func_interp_set_else(self.ctx.z3_ctx.0, self.z3_func_interp, ast.z3_ast) }
70 }
71}
72
73impl fmt::Display for FuncInterp {
74 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
75 write!(f, "[")?;
76 self.get_entries().into_iter().try_for_each(|e| {
77 let n = e.get_num_args();
78 if n > 1 {
79 write!(f, "[")?;
80 };
81 write!(
82 f,
83 "{}",
84 e.get_args()
85 .into_iter()
86 .map(|a| a.to_string())
87 .collect::<Vec<_>>()
88 .join(", ")
89 )?;
90 if n > 1 {
91 write!(f, "]")?;
92 }
93 write!(f, " -> {}, ", e.get_value())
94 })?;
95 write!(f, "else -> {}", self.get_else())?;
96 write!(f, "]")
97 }
98}
99
100impl fmt::Debug for FuncInterp {
101 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
102 <Self as fmt::Display>::fmt(self, f)
103 }
104}
105
106impl Drop for FuncInterp {
107 fn drop(&mut self) {
108 unsafe {
109 Z3_func_interp_dec_ref(self.ctx.z3_ctx.0, self.z3_func_interp);
110 }
111 }
112}