1#![warn(clippy::pedantic)]
25#![warn(missing_docs)]
26#![warn(missing_debug_implementations)]
27
28use rustsat::{solvers::SolverState, types::Var};
29use std::{ffi::c_int, fmt};
30use thiserror::Error;
31
32pub mod core;
33pub mod simp;
34
35#[derive(Error, Clone, Copy, PartialEq, Eq, Debug)]
37#[error("glucose c-api returned an invalid value: {api_call} -> {value}")]
38pub struct InvalidApiReturn {
39 api_call: &'static str,
40 value: c_int,
41}
42
43#[derive(Error, Clone, Copy, PartialEq, Eq, Debug)]
48#[error("assumption variable {0} has been eliminated by glucose simplification")]
49pub struct AssumpEliminated(Var);
50
51#[derive(Debug, PartialEq, Eq, Default)]
52enum InternalSolverState {
53 #[default]
54 Configuring,
55 Input,
56 Sat,
57 Unsat(bool),
58}
59
60impl InternalSolverState {
61 fn to_external(&self) -> SolverState {
62 match self {
63 InternalSolverState::Configuring => SolverState::Configuring,
64 InternalSolverState::Input => SolverState::Input,
65 InternalSolverState::Sat => SolverState::Sat,
66 InternalSolverState::Unsat(_) => SolverState::Unsat,
67 }
68 }
69}
70
71#[derive(Debug, Clone, Copy)]
73pub enum Limit {
74 None,
76 Conflicts(i64),
78 Propagations(i64),
80}
81
82impl fmt::Display for Limit {
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 match self {
85 Limit::None => write!(f, "none"),
86 Limit::Conflicts(val) => write!(f, "conflicts ({val})"),
87 Limit::Propagations(val) => write!(f, "propagations ({val})"),
88 }
89 }
90}
91
92macro_rules! handle_oom {
93 ($val:expr) => {{
94 let val = $val;
95 if val == $crate::ffi::OUT_OF_MEM {
96 return anyhow::Context::context(
97 Err(rustsat::OutOfMemory::ExternalApi),
98 "glucose out of memory",
99 );
100 }
101 val
102 }};
103}
104pub(crate) use handle_oom;
105
106pub(crate) mod ffi {
107 #![allow(non_upper_case_globals)]
108 #![allow(non_camel_case_types)]
109 #![allow(non_snake_case)]
110
111 use std::os::raw::c_void;
112
113 use rustsat::types::Lit;
114
115 include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
116
117 impl From<Lit> for c_Lit {
118 fn from(value: Lit) -> Self {
119 unsafe { std::mem::transmute::<Lit, c_Lit>(value) }
120 }
121 }
122
123 pub extern "C" fn rustsat_glucose_collect_lits(vec: *mut c_void, lit: c_Lit) {
124 let vec = vec.cast::<Vec<Lit>>();
125 unsafe { (*vec).push(std::mem::transmute::<c_Lit, Lit>(lit)) };
126 }
127}