mod dimacs;
pub use dimacs::parse_dimacs_cnf;
pub use dimacs::read_dimacs_from_file;
pub use dimacs::read_dimacs_from_reader;
pub(crate) use dimacs::Rule;
use crate::errors::ParserError;
use crate::solver::SatSolver;
#[cfg(feature = "parser")]
pub struct Problem {
pub clauses: Vec<Vec<i32>>,
pub num_vars: usize,
pub num_clauses: usize,
}
#[cfg(feature = "parser")]
impl Default for Problem {
fn default() -> Self {
Self::new()
}
}
impl Problem {
pub fn new() -> Self {
Self {
clauses: vec![],
num_vars: 0,
num_clauses: 0,
}
}
}
pub trait AsDimacs {
fn push_clause(&mut self, clause: Vec<i32>)->Result<(),ParserError>;
fn add_comment(&mut self, comment: String);
}
impl<T: SatSolver> AsDimacs for T {
fn push_clause(&mut self, clause: Vec<i32>) ->Result<(),ParserError>{
SatSolver::push_clause(self, &clause)?;
Ok(())
}
fn add_comment(&mut self, _comment: String) {}
}
impl AsDimacs for Vec<Vec<i32>> {
fn push_clause(&mut self, clause: Vec<i32>)->Result<(),ParserError> {
self.push(clause);
Ok(())
}
fn add_comment(&mut self, _comment: String) {
}
}
impl AsDimacs for Problem {
fn push_clause(&mut self, clause: Vec<i32>) ->Result<(),ParserError> {
let max = clause.iter().map(|v| v.abs()).max().unwrap_or(0);
self.num_vars = self.num_vars.max(max as usize);
self.clauses.push(clause);
self.num_clauses += 1;
Ok(())
}
fn add_comment(&mut self, _comment: String) {}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn dimacs() {
let dimacs_content = "c This is a comment
p cnf 3 2
1 -3 0
";
let mut cnf=Vec::new();
match parse_dimacs_cnf(dimacs_content, false,&mut cnf) {
Ok(_) => {
assert_eq!(cnf.len(), 1);
}
Err(_e) => assert_eq!("result", "should be ok"),
}
}
#[test]
fn dimacs_strict() {
let dimacs_content = "c This is a comment
p cnf 2 2
1 -3 0
";
let mut cnf=Vec::new();
assert!(matches!(parse_dimacs_cnf(dimacs_content, true,&mut cnf), Err(_)));
}
}