use super::ast::*;
use std::collections::VecDeque;
pub fn to_disjunctive_normal_form(top_disjunction : &mut Disjunction) {
let mut additional_conjunctions = VecDeque::new();
for top_conjunction in top_disjunction.iter_mut() {
let top_conjunction : &mut Conjunction = top_conjunction;
let mut literal_factors : Vec<Literal> = Vec::new();
let mut disjunction_factors : Vec<Disjunction> = Vec::new();
for f in top_conjunction.drain(..) {
match f {
Factor::Disjunction(mut inner_disjunction) => {
to_disjunctive_normal_form(&mut inner_disjunction);
disjunction_factors.push(inner_disjunction);
},
Factor::Literal(l) => {
literal_factors.push(l);
},
}
}
if disjunction_factors.is_empty() {
for f in literal_factors.into_iter() {
top_conjunction.push_back(Factor::Literal(f));
}
} else {
for child_disjunct in disjunction_factors.into_iter() {
for child_conjunct in child_disjunct.into_iter() {
let mut new_conjunction : Conjunction = Conjunction::new();
for existing_literal in literal_factors.iter() {
new_conjunction.push_back(Factor::Literal(existing_literal.clone()));
}
for new_literal in child_conjunct.into_iter() {
new_conjunction.push_back(new_literal);
}
additional_conjunctions.push_back(new_conjunction);
}
}
}
}
top_disjunction.append(&mut additional_conjunctions);
top_disjunction.retain(|ref c| !c.is_empty());
}