use crate::notation::Literal;
use crate::notation::Clause;
use crate::notation::Formula;
pub fn parse_cnf(_buffer: &str) -> Result<Formula, String> {
let mut num_clauses: i32 = 0;
let mut num_vars: i32 = 0;
let mut clauses: Vec<Clause> = Vec::new();
for line in _buffer.lines() {
if line.starts_with("c") {
continue;
} else if line.starts_with("p") {
let mut tokens = line.split_whitespace();
for _ in 0..2 {
if tokens.next().is_none() {
return Err("Not enough tokens in the line".to_string());
}
}
let num_vars_str = tokens.next().ok_or("Missing num_vars token")?;
num_vars = num_vars_str.parse::<i32>().map_err(|e| format!("Failed to parse num_vars: {}", e))?;
let num_clauses_str = tokens.next().ok_or("Missing num_clauses token")?;
num_clauses = num_clauses_str.parse::<i32>().map_err(|e| format!("Failed to parse num_clauses: {}", e))?;
} else {
let mut clause: Clause = Clause::new();
for token in line.split_whitespace() {
let _lit = token.parse::<i32>().unwrap();
if _lit == 0 {
break;
}
let literal = Literal{
value: _lit.abs(),
negated: _lit < 0
};
clause.literals.push(literal);
}
clauses.push(clause);
}
}
let mut literals: Vec<i32> = Vec::new();
for clause in &clauses {
for literal in &clause.literals {
if !literals.contains(&literal.value) {
literals.push(literal.value);
}
}
}
assert_eq!(num_clauses, clauses.len() as i32);
assert_eq!(num_vars, literals.len() as i32);
let formula: Formula = Formula {
clauses: clauses,
literals: literals,
num_clauses: num_clauses,
num_vars: num_vars,
};
Ok(formula)
}