Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bindings for global params #242

Merged
merged 1 commit into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions z3/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::ffi::CString;
use z3_sys::*;
use Config;
use Context;
Expand Down Expand Up @@ -29,6 +30,28 @@ impl Context {
pub fn handle(&self) -> ContextHandle {
ContextHandle { ctx: self }
}

/// Update a global parameter.
///
/// # See also
///
/// - [`Context::update_bool_param_value()`]
pub fn update_param_value(&mut self, k: &str, v: &str) {
let ks = CString::new(k).unwrap();
let vs = CString::new(v).unwrap();
unsafe { Z3_update_param_value(self.z3_ctx, ks.as_ptr(), vs.as_ptr()) };
}

/// Update a global parameter.
///
/// This is a helper function.
///
/// # See also
///
/// - [`Context::update_param_value()`]
pub fn update_bool_param_value(&mut self, k: &str, v: bool) {
self.update_param_value(k, if v { "true" } else { "false" })
}
}

impl<'ctx> ContextHandle<'ctx> {
Expand Down
1 change: 1 addition & 0 deletions z3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ mod statistics;
mod symbol;
mod tactic;

pub use params::{get_global_param, reset_all_global_params, set_global_param};
pub use statistics::{StatisticsEntry, StatisticsValue};

/// Configuration used to initialize [logical contexts](Context).
Expand Down
41 changes: 40 additions & 1 deletion z3/src/params.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::ffi::CStr;
use std::ffi::{CStr, CString};
use std::fmt;
use z3_sys::*;
use Context;
Expand Down Expand Up @@ -60,6 +60,45 @@ impl<'ctx> Params<'ctx> {
}
}

/// Get a global (or module) parameter.
///
/// # See also
///
/// - [`set_global_param()`]
/// - [`reset_all_global_params()`]
pub fn get_global_param(k: &str) -> Option<String> {
let ks = CString::new(k).unwrap();
let mut ptr = std::ptr::null();
if unsafe { Z3_global_param_get(ks.as_ptr(), &mut ptr as *mut *const i8) } {
let vs = unsafe { CStr::from_ptr(ptr) };
vs.to_str().ok().map(|vs| vs.to_owned())
} else {
None
}
}

/// Set a global (or module) parameter. This setting is shared by all Z3 contexts.
///
/// # See also
///
/// - [`get_global_param()`]
/// - [`reset_all_global_params()`]
pub fn set_global_param(k: &str, v: &str) {
let ks = CString::new(k).unwrap();
let vs = CString::new(v).unwrap();
unsafe { Z3_global_param_set(ks.as_ptr(), vs.as_ptr()) };
}

/// Restore the value of all global (and module) parameters. This command will not affect already created objects (such as tactics and solvers).
///
/// # See also
///
/// - [`get_global_param()`]
/// - [`set_global_param()`]
pub fn reset_all_global_params() {
unsafe { Z3_global_param_reset_all() };
}

impl<'ctx> fmt::Display for Params<'ctx> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let p = unsafe { Z3_params_to_string(self.ctx.z3_ctx, self.z3_params) };
Expand Down
17 changes: 17 additions & 0 deletions z3/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,23 @@ fn test_params() {
assert_eq!(solver.check(), SatResult::Sat);
}

#[test]
fn test_global_params() {
let _ = env_logger::try_init();
// could interfere with other tests if they use global params
reset_all_global_params();
let val = get_global_param("iDontExist");
assert_eq!(val, None);
let val = get_global_param("verbose");
assert_eq!(val, Some("0".into()));
set_global_param("verbose", "1");
let val = get_global_param("verbose");
assert_eq!(val, Some("1".into()));
reset_all_global_params();
let val = get_global_param("verbose");
assert_eq!(val, Some("0".into()));
}

#[test]
fn test_substitution() {
let cfg = Config::new();
Expand Down