feat(ex06): generate karnaugh map func
This commit is contained in:
parent
17789f1a2d
commit
ccde9fa539
|
@ -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)
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
|
@ -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]
|
||||
|
|
|
@ -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|&");
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue