ddnnife 0.10.0

d-DNNF toolkit
Documentation
use rand::Rng;
use std::iter;

#[cfg(any(feature = "deterministic", test))]
use rand::prelude::{SeedableRng, StdRng};

pub fn format_vec_separated_by<T: ToString>(
    vals: impl Iterator<Item = T>,
    separator: &str,
) -> String {
    vals.map(|v| v.to_string())
        .collect::<Vec<String>>()
        .join(separator)
}

pub fn format_vec<T: ToString>(vals: impl Iterator<Item = T>) -> String {
    format_vec_separated_by(vals, " ")
}

pub fn format_vec_vec<T>(vals: impl Iterator<Item = T>) -> String
where
    T: IntoIterator,
    T::Item: ToString,
{
    vals.map(|res| format_vec(res.into_iter()))
        .collect::<Vec<String>>()
        .join(";")
}

#[cfg(any(feature = "deterministic", test))]
#[inline]
pub fn rng() -> impl Rng {
    StdRng::seed_from_u64(42)
}

#[cfg(not(any(feature = "deterministic", test)))]
#[inline]
pub fn rng() -> impl Rng {
    rand::rng()
}

pub fn zip_assumptions_variables<'a>(
    assumptions: &'a [i32],
    variables: &'a [i32],
) -> Box<dyn Iterator<Item = Vec<i32>> + 'a> {
    if assumptions.is_empty() && variables.is_empty() {
        return Box::new(iter::once(Vec::new()));
    }

    if assumptions.is_empty() {
        return Box::new(variables.iter().copied().map(|variable| vec![variable]));
    }

    if variables.is_empty() {
        return Box::new(iter::once(assumptions.to_vec()));
    }

    Box::new(
        iter::repeat(assumptions)
            .zip(variables.iter())
            .map(|(assumptions, &variable)| {
                let mut assumptions = assumptions.to_vec();
                assumptions.push(variable);
                assumptions
            }),
    )
}