logicng 0.1.0-alpha.3

A Library for Creating, Manipulating, and Solving Boolean Formulas
Documentation
use crate::formulas::{EncodedFormula, FormulaFactory};

mod assume_tests;
mod inc_dec_tests;
#[cfg(feature = "open_wbo")]
mod maxsat_tests;
mod sat_tests;

pub fn generate_pigeon_hole(n: usize, f: &FormulaFactory) -> EncodedFormula {
    generate_pigeon_hole_with_prefix(n, "v", f)
}

pub fn generate_pigeon_hole_with_prefix(n: usize, prefix: &str, f: &FormulaFactory) -> EncodedFormula {
    let some_hole = place_in_some_hole(n, prefix, f);
    let one_pigeon = only_one_pigeon_in_hole(n, prefix, f);
    f.and(&[some_hole, one_pigeon])
}

fn place_in_some_hole(n: usize, prefix: &str, f: &FormulaFactory) -> EncodedFormula {
    if n == 1 {
        let v1 = f.variable(&format!("{prefix}1"));
        let v2 = f.variable(&format!("{prefix}2"));
        f.and(&[v1, v2])
    } else {
        let mut ors = Vec::with_capacity(n + 1);
        for i in 1..=(n + 1) {
            let mut or_ops = Vec::with_capacity(n);
            for j in 1..=n {
                or_ops.push(f.variable(&format!("{prefix}{}", n * (i - 1) + j)));
            }
            ors.push(f.or(&or_ops));
        }
        f.and(&ors)
    }
}

fn only_one_pigeon_in_hole(n: usize, prefix: &str, f: &FormulaFactory) -> EncodedFormula {
    if n == 1 {
        let v1 = f.literal(&format!("{prefix}1"), false);
        let v2 = f.literal(&format!("{prefix}2"), false);
        f.and(&[v1, v2])
    } else {
        let mut ors = Vec::with_capacity(n + 1);
        for i in 1..=n {
            for j in 1..=n {
                for k in (j + 1)..=(n + 1) {
                    let v1 = f.literal(&format!("{prefix}{}", n * (j - 1) + i), false);
                    let v2 = f.literal(&format!("{prefix}{}", n * (k - 1) + i), false);
                    ors.push(f.or(&[v1, v2]));
                }
            }
        }
        f.and(&ors)
    }
}