use crate::ffi_apis::common::BincodeBuffer;
use crate::ffi_apis::common::from_bincode_buffer;
use crate::ffi_apis::common::to_bincode_buffer;
use crate::symbolic::core::Expr;
use crate::symbolic::number_theory::chinese_remainder;
use crate::symbolic::number_theory::extended_gcd;
use crate::symbolic::number_theory::is_prime;
use crate::symbolic::number_theory::solve_diophantine;
#[derive(serde::Deserialize)]
struct Congruence {
remainder: Expr,
modulus: Expr,
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_bincode_solve_diophantine(
equation_buf: BincodeBuffer,
vars_buf: BincodeBuffer,
) -> BincodeBuffer {
let equation: Option<Expr> = from_bincode_buffer(&equation_buf);
let vars: Option<Vec<String>> = from_bincode_buffer(&vars_buf);
match (equation, vars) {
| (Some(eq), Some(v)) => {
let v_str: Vec<&str> = v.iter().map(std::string::String::as_str).collect();
match solve_diophantine(&eq, &v_str) {
| Ok(solutions) => to_bincode_buffer(&solutions),
| Err(_) => BincodeBuffer::empty(),
}
},
| _ => BincodeBuffer::empty(),
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_bincode_extended_gcd(
a_buf: BincodeBuffer,
b_buf: BincodeBuffer,
) -> BincodeBuffer {
let a: Option<Expr> = from_bincode_buffer(&a_buf);
let b: Option<Expr> = from_bincode_buffer(&b_buf);
match (a, b) {
| (Some(a_expr), Some(b_expr)) => {
let (g, x, y) = extended_gcd(&a_expr, &b_expr);
to_bincode_buffer(&(g, x, y))
},
| _ => BincodeBuffer::empty(),
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_bincode_is_prime(n_buf: BincodeBuffer) -> BincodeBuffer {
let n: Option<Expr> = from_bincode_buffer(&n_buf);
if let Some(n_expr) = n {
let result = is_prime(&n_expr);
to_bincode_buffer(&result)
} else {
BincodeBuffer::empty()
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_bincode_chinese_remainder(congruences_buf: BincodeBuffer) -> BincodeBuffer {
let congruences_input: Option<Vec<Congruence>> = from_bincode_buffer(&congruences_buf);
if let Some(input) = congruences_input {
let congruences: Vec<(Expr, Expr)> = input
.into_iter()
.map(|c| (c.remainder, c.modulus))
.collect();
match chinese_remainder(&congruences) {
| Some(result) => to_bincode_buffer(&result),
| None => BincodeBuffer::empty(),
}
} else {
BincodeBuffer::empty()
}
}