1use ocas_calc::solve::{
4 DiophantineSolution, SolveError, solve_diophantine as rs_diophantine,
5 solve_linear_integer as rs_linear_integer, solve_linear_rational as rs_linear_rational,
6};
7use pyo3::exceptions::PyValueError;
8use pyo3::prelude::*;
9
10fn map_solve_err(e: SolveError) -> PyErr {
11 PyValueError::new_err(e.to_string())
12}
13
14#[pyfunction]
20#[pyo3(name = "solve_linear_rational")]
21pub fn py_solve_linear_rational(a: Vec<Vec<i64>>, b: Vec<i64>) -> PyResult<Vec<(i64, i64)>> {
22 rs_linear_rational(&a, &b).map_err(map_solve_err)
23}
24
25#[pyfunction]
30#[pyo3(name = "solve_linear_integer")]
31pub fn py_solve_linear_integer(a: Vec<Vec<i64>>, b: Vec<i64>) -> PyResult<Vec<i64>> {
32 rs_linear_integer(&a, &b).map_err(map_solve_err)
33}
34
35#[pyclass(name = "DiophantineSolution")]
37pub struct PyDiophantineSolution {
38 #[pyo3(get)]
40 pub particular: (i64, i64),
41 #[pyo3(get)]
44 pub general: (i64, i64),
45}
46
47impl From<DiophantineSolution> for PyDiophantineSolution {
48 fn from(s: DiophantineSolution) -> Self {
49 PyDiophantineSolution {
50 particular: s.particular,
51 general: s.general,
52 }
53 }
54}
55
56#[pyfunction]
60#[pyo3(name = "solve_diophantine")]
61pub fn py_solve_diophantine(a: i64, b: i64, c: i64) -> Option<PyDiophantineSolution> {
62 rs_diophantine(a, b, c).map(Into::into)
63}