mod handle;
pub use crate::translate::synchronization::handle::Synchronized;
use crate::{Config, Context, Translate};
use std::sync::Mutex;
pub trait PrepareSynchronized {
type Inner;
fn synchronized(&self) -> Synchronized<Self::Inner>;
}
impl<T: Translate> PrepareSynchronized for &[T] {
type Inner = Vec<T>;
fn synchronized(&self) -> Synchronized<Self::Inner> {
let ctx = Context::new(&Config::new());
let data: Vec<T> = self.iter().map(|t| t.translate(&ctx)).collect();
Synchronized(Mutex::new(data))
}
}
impl<T: Translate> PrepareSynchronized for T {
type Inner = T;
fn synchronized(&self) -> Synchronized<Self::Inner> {
Synchronized::new(self)
}
}
#[cfg(test)]
#[cfg(not(target_arch = "wasm32"))]
mod thread_tests {
use crate::Solver;
use crate::ast::Bool;
use crate::translate::synchronization::PrepareSynchronized;
#[test]
fn test_send() {
let bv = Bool::from_bool(true);
let sendable = bv.synchronized();
std::thread::spawn(move || {
let moved = sendable.recover();
assert_eq!(moved.as_bool(), Some(true));
})
.join()
.expect("uh oh");
}
#[test]
fn test_send_vec() {
let bv = vec![Bool::from_bool(true); 8];
let sendable = bv.synchronized();
std::thread::spawn(move || {
let moved = sendable.recover();
for x in moved {
assert_eq!(x.as_bool(), Some(true));
}
})
.join()
.expect("uh oh");
}
#[test]
fn test_round_trip() {
let bool = Bool::new_const("hello");
let sendable = bool.synchronized();
let model = std::thread::spawn(move || {
let moved = sendable.recover();
let solver = Solver::new();
solver.assert(moved);
solver.check();
let model = solver.get_model().unwrap();
model.synchronized()
})
.join()
.expect("uh oh");
let model = model.recover();
assert_eq!(model.eval(&bool, true), Some(Bool::from_bool(true)));
}
}
#[cfg(test)]
mod rayon_tests {
use crate::ast::Int;
use crate::{PrepareSynchronized, Solver};
use std::ops::Add;
#[test]
fn test_rayon() {
use rayon::prelude::*;
let int = Int::fresh_const("hello").add(2);
let sendable = int.synchronized();
(0..100).into_par_iter().for_each(|i| {
let moved = sendable.recover();
let solver = Solver::new();
solver.assert(moved.eq(i));
assert_eq!(solver.check(), crate::SatResult::Sat);
let model = solver.get_model().unwrap();
assert_eq!(model.eval(&moved, true).unwrap(), i);
})
}
}