use pyo3::prelude::*;
use super::enums::{Ordering, Pruning};
use crate::{CancelToken as RustCancelToken, SolveConfig as RustSolveConfig};
#[pyclass(from_py_object)]
#[derive(Clone, Default)]
pub struct CancelToken {
pub(super) inner: RustCancelToken,
}
#[pymethods]
impl CancelToken {
#[new]
fn new() -> Self {
Self {
inner: RustCancelToken::new(),
}
}
fn cancel(&self) {
self.inner.cancel();
}
#[getter]
fn is_cancelled(&self) -> bool {
self.inner.is_cancelled()
}
}
#[pyclass(skip_from_py_object)]
#[derive(Clone)]
pub struct SolveConfig {
#[pyo3(get, set)]
pub pruning: Pruning,
#[pyo3(get, set)]
pub ordering: Ordering,
#[pyo3(get, set)]
pub max_solutions: usize,
#[pyo3(get, set)]
pub node_budget: Option<u64>,
#[pyo3(get, set)]
pub cancel: Option<CancelToken>,
}
#[pymethods]
impl SolveConfig {
#[new]
#[pyo3(signature = (pruning=Pruning::FORWARD_CHECKING, ordering=Ordering::CHRONOLOGICAL, max_solutions=1, node_budget=Some(1_000_000), cancel=None))]
fn new(
pruning: Pruning,
ordering: Ordering,
max_solutions: usize,
node_budget: Option<u64>,
cancel: Option<CancelToken>,
) -> Self {
Self {
pruning,
ordering,
max_solutions,
node_budget,
cancel,
}
}
}
impl From<&SolveConfig> for RustSolveConfig {
fn from(c: &SolveConfig) -> Self {
RustSolveConfig {
pruning: c.pruning.into(),
ordering: c.ordering.into(),
max_solutions: c.max_solutions,
node_budget: c.node_budget,
cancel: c.cancel.as_ref().map(|t| t.inner.clone()),
..Default::default()
}
}
}
#[pyclass(skip_from_py_object)]
#[derive(Clone)]
pub struct SolveStats {
#[pyo3(get)]
pub backtracks: u64,
#[pyo3(get)]
pub nodes_explored: u64,
#[pyo3(get)]
pub propagations: u64,
#[pyo3(get)]
pub budget_exceeded: bool,
#[pyo3(get)]
pub cancelled: bool,
}