ready_set_boole/src/conjunctive_normal_form.rs

69 lines
2.1 KiB
Rust

mod tests;
use crate::ast::Node;
use crate::boolean_evaluation::eval_formula;
use crate::gray_code::gray_code;
fn get_variables(formula: &str) -> Vec<char> {
let mut v: Vec<char> = formula.chars().collect();
v.sort();
v.dedup();
v.into_iter().filter(|x| x.is_ascii_uppercase()).collect()
}
fn bool_to_str(a: u32) -> &'static str {
match a {
0 => "0",
_ => "1"
}
}
fn replace_var(formula: &str, variables: &[char], size: (usize, usize), coor: (u32, u32)) -> String {
let gray_x = gray_code(coor.0);
let gray_y = gray_code(coor.1);
let mut ret = String::from(formula);
dbg!(size);
dbg!(coor);
for i in 0..size.0 {
ret = ret.as_str().replace(variables[i], bool_to_str(gray_x & 1 << i));
}
for i in 0..size.1 {
ret = ret.as_str().replace(variables[size.0 + i], bool_to_str(gray_y & 1 << i));
}
dbg!(&ret);
String::from(ret)
}
fn get_karnaugh_map(formula: &str, variables: &[char]) -> Vec<Vec<bool>> {
let lines = (variables.len()+1)/2;
let columns = variables.len() - lines;
let mut map = vec![];
for y in 0..1<<lines {
map.push(vec![]);
for x in 0..1<<columns {
map.last_mut().unwrap().push(eval_formula(replace_var(formula, variables, (lines, columns), (y, x)).as_str()));
}
}
map
}
fn map_to_formula(map: Vec<Vec<bool>>, variables: &[char]) -> String {
dbg!(map);
String::from("")
}
pub fn conjunctive_normal_form(formula: &str) -> String {
let variables = &get_variables(formula);
if variables.len() == 1 {
return match (eval_formula(formula.replace(variables[0], "0").as_str()),
eval_formula(formula.replace(variables[0], "1").as_str())) {
(false, false) => "AA!&".replace("A", &variables[0].to_string()),
(false, true) => String::from(variables[0]),
(true, false) => "A!".replace("A", &variables[0].to_string()),
(true, true) => "AA!|".replace("A", &variables[0].to_string())
}
}
let map = get_karnaugh_map(formula, variables);
map_to_formula(map, variables)
}