feat(ex06): generate karnaugh map func

This commit is contained in:
gbrochar 2024-01-25 18:42:09 +01:00
parent 17789f1a2d
commit ccde9fa539
4 changed files with 130 additions and 10 deletions

View File

@ -0,0 +1,68 @@
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)
}

View File

@ -0,0 +1,48 @@
#[cfg(test)]
mod tests {
use std::env::current_dir;
use crate::conjunctive_normal_form::{conjunctive_normal_form, get_karnaugh_map};
#[test]
fn subject_tests() {
assert_eq!(conjunctive_normal_form("AB&!"), "A!B!|");
assert_eq!(conjunctive_normal_form("AB|!"), "A!B!&");
assert_eq!(conjunctive_normal_form("AB|C&"), "AB|C&");
assert_eq!(conjunctive_normal_form("AB|C|D|"), "ABCD|||");
assert_eq!(conjunctive_normal_form("AB&C&D&"), "ABCD&&&");
assert_eq!(conjunctive_normal_form("AB&!C!|"), "A!B!C!||");
assert_eq!(conjunctive_normal_form("AB|!C!&"), "A!B!C!&&");
}
#[test]
fn my_test() {
assert_eq!(conjunctive_normal_form("ABC&&"), "ABC&&");
assert_eq!(conjunctive_normal_form("AAA&&"), "A");
}
#[test]
fn karnaugh_map() {
assert_eq!(get_karnaugh_map("ABC&&", &vec!['A', 'B', 'C']), vec![
vec![false, false],
vec![false, false],
vec![false, true],
vec![false, false],
]);
assert_eq!(get_karnaugh_map("AB^CD=&", &vec!['A', 'B', 'C', 'D']), vec![
vec![false, false, false, false],
vec![true, false, true, false],
vec![false, false, false, false],
vec![true, false, true, false],
]);
}
#[test]
fn one_var() {
assert_eq!(conjunctive_normal_form("AAA&&"), "A");
assert_eq!(conjunctive_normal_form("AAA!&&"), "AA!&");
assert_eq!(conjunctive_normal_form("AAA!|&"), "A");
assert_eq!(conjunctive_normal_form("AAA!||"), "AA!|");
assert_eq!(conjunctive_normal_form("A!A!A!&&"), "A!");
}
}

View File

@ -4,16 +4,16 @@ mod tests {
#[test]
fn digits() {
assert_eq!(gray_code(0), 0);
assert_eq!(gray_code(1), 1);
assert_eq!(gray_code(2), 3);
assert_eq!(gray_code(3), 2);
assert_eq!(gray_code(4), 6);
assert_eq!(gray_code(5), 7);
assert_eq!(gray_code(6), 5);
assert_eq!(gray_code(7), 4);
assert_eq!(gray_code(8), 12);
assert_eq!(gray_code(9), 13);
assert_eq!(gray_code(0), 0b0000);
assert_eq!(gray_code(1), 0b0001);
assert_eq!(gray_code(2), 0b0011);
assert_eq!(gray_code(3), 0b0010);
assert_eq!(gray_code(4), 0b0110);
assert_eq!(gray_code(5), 0b0111);
assert_eq!(gray_code(6), 0b0101);
assert_eq!(gray_code(7), 0b0100);
assert_eq!(gray_code(8), 0b1100);
assert_eq!(gray_code(9), 0b1101);
}
#[test]

View File

@ -4,6 +4,7 @@ mod boolean_evaluation;
mod gray_code;
mod multiplier;
mod negation_normal_form;
mod conjunctive_normal_form;
mod truth_table;
use gray_code::gray_code;
@ -23,6 +24,7 @@ fn main() {
println!("{}", gray_code(3));
print_truth_table("ZFG|&");
print_truth_table("ABC|&");
print_truth_table("AY&BZ|&");
let formula = "AB=CD^|!AD!^!&!";
println!("{formula}");
print_truth_table(formula);
@ -30,4 +32,6 @@ fn main() {
println!("{formula}");
print_truth_table(formula);
print_truth_table("AZ&BY|&");
}