use std::io::{Error, ErrorKind};
use logos::Lexer;
use veripb_formula::prelude::*;
use crate::assignment_token::AssignmentToken;
pub fn parse_bool_assignment(
lex: &mut Lexer<AssignmentToken>,
var_names: &mut VarNameManager,
) -> Result<Assignment<BooleanVar>, Error> {
let mut assignment = Assignment::with_size(var_names.len());
parse_bool_assignment_into(lex, var_names, &mut assignment)?;
Ok(assignment)
}
pub fn parse_bool_assignment_into(
lex: &mut Lexer<AssignmentToken>,
var_names: &mut VarNameManager,
assignment: &mut Assignment<BooleanVar>,
) -> Result<(), Error> {
assignment.resize(var_names.len());
while let Some(lit) = lex.next() {
match lit {
Ok(AssignmentToken::PositiveVar) => {
let var = var_names.add_by_name(lex.slice());
if var >= assignment.len() {
assignment.resize(var + 1);
}
assignment.set_value(var, BoolValue::Assigned(true));
}
Ok(AssignmentToken::NegativeVar) => {
let var = var_names.add_by_name(&lex.slice()[1..]);
if var >= assignment.len() {
assignment.resize(var + 1);
}
assignment.set_value(var, BoolValue::Assigned(false));
}
Err(_) => {
return Err(Error::new(
ErrorKind::InvalidData,
format!("The token '{}' is not a literal!", lex.slice()),
));
}
}
}
Ok(())
}
pub fn parse_bool_assignment_to_raw_vec(
lex: &mut Lexer<AssignmentToken>,
var_names: &mut VarNameManager,
) -> Result<Vec<Lit>, Error> {
let mut assignment = Vec::new();
while let Some(lit) = lex.next() {
match lit {
Ok(AssignmentToken::PositiveVar) => {
let var = var_names.add_by_name(lex.slice());
assignment.push(Lit::from_var(var, false));
}
Ok(AssignmentToken::NegativeVar) => {
let var = var_names.add_by_name(&lex.slice()[1..]);
assignment.push(Lit::from_var(var, true));
}
Err(_) => {
return Err(Error::new(
ErrorKind::InvalidData,
format!("The token '{}' is not a literal!", lex.slice()),
));
}
}
}
Ok(assignment)
}