1use aig::Aig;
2use std::{
3 env,
4 ffi::{CString, c_char, c_void},
5};
6
7unsafe extern "C" {
8 fn Abc_FrameGetGlobalFrame() -> *mut c_void;
9 fn Abc_Stop();
10 fn Cmd_CommandExecute(pAbc: *mut c_void, sCommand: *const c_char) -> i32;
11}
12
13pub struct Abc {
14 ptr: *mut c_void,
15}
16
17impl Drop for Abc {
18 fn drop(&mut self) {
19 unsafe { Abc_Stop() };
20 }
21}
22
23impl Abc {
24 pub fn new() -> Self {
25 let ptr = unsafe { Abc_FrameGetGlobalFrame() };
26 assert!(!ptr.is_null(), "init abc failed");
27 Self { ptr }
28 }
29
30 pub fn execute_command(&mut self, command: &str) {
31 let c = CString::new(command).unwrap();
32 let res = unsafe { Cmd_CommandExecute(self.ptr, c.as_ptr()) };
33 assert!(res == 0, "abc execute {command} failed");
34 }
35
36 pub fn read_aig(&mut self, aig: &Aig) {
37 let dir = match env::var("RIC3_TMP_DIR") {
38 Ok(d) => d,
39 Err(_) => "/tmp/rIC3".to_string(),
40 };
41 let tmpfile = tempfile::NamedTempFile::new_in(dir).unwrap();
42 aig.to_file(tmpfile.path(), false);
43 let command = format!("read_aiger {};", tmpfile.path().display());
44 let command = CString::new(command).unwrap();
45 let res = unsafe { Cmd_CommandExecute(self.ptr, command.as_ptr()) };
46 assert!(res == 0, "abc read aig failed");
47 }
48
49 pub fn write_aig(&mut self) -> Aig {
50 let dir = match env::var("RIC3_TMP_DIR") {
51 Ok(d) => d,
52 Err(_) => "/tmp/rIC3".to_string(),
53 };
54 let tmpfile = tempfile::NamedTempFile::new_in(dir).unwrap();
55 let path = tmpfile.path().as_os_str().to_str().unwrap();
56 let command = format!("write_aiger {};", path);
57 let command = CString::new(command).unwrap();
58 let res = unsafe { Cmd_CommandExecute(self.ptr, command.as_ptr()) };
59 assert!(res == 0, "abc write aig failed");
60 Aig::from_file(path)
61 }
62}
63
64impl Default for Abc {
65 fn default() -> Self {
66 Self::new()
67 }
68}