diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 157 |
1 files changed, 61 insertions, 96 deletions
diff --git a/src/main.rs b/src/main.rs index 95d5b7b..bc22521 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,44 +37,6 @@ impl Cube { } } -fn cube_to_string(n: usize, cube: &Cube) -> String { - let mut s = String::new(); - - let Cube { mut t, mut f } = *cube; - for _ in 0..n { - match (t & 1, f & 1) { - (1, 0) => s.push('1'), - (0, 1) => s.push('0'), - (0, 0) => s.push('x'), - _ => unreachable!(), - } - - t >>= 1; - f >>= 1; - } - - s.chars().rev().collect() -} - -fn cube_to_var_string(vars: &[&str], cube: &Cube) -> String { - let mut used_vars: Vec<String> = Vec::with_capacity(vars.len()); - - let Cube { mut t, mut f } = *cube; - for i in (0..vars.len()).rev() { - match (t & 1, f & 1) { - (1, 0) => used_vars.push(vars[i].into()), - (0, 1) => used_vars.push(format!("{}'", vars[i])), - (0, 0) => (), - _ => unreachable!(), - } - - t >>= 1; - f >>= 1; - } - - used_vars.into_iter().rev().join(" * ") -} - fn minimize_prime_implicants(n: usize, minterms: &[usize], maxterms: &[usize]) -> Vec<Cube> { let minterms_set: HashSet<_> = minterms.iter().copied().collect(); let maxterms_set: HashSet<_> = maxterms.iter().copied().collect(); @@ -131,35 +93,6 @@ fn minimize_prime_implicants(n: usize, minterms: &[usize], maxterms: &[usize]) - final_cubes } -fn print_prime_implicants_table(n: usize, minterms: &[usize], prime_implicants: &[Cube]) { - println!("Prime implicants:"); - for (i, prime_implicant) in prime_implicants.iter().enumerate() { - let cube_str = cube_to_string(n, prime_implicant); - println!("{i}: {cube_str}"); - } - - println!(); - println!("Prime Implicants Table (PIT):"); - print!(" "); - println!( - "{}", - (0..minterms.len()) - .map(|i| format!(" {} ", minterms[i])) - .join("") - ); - for (i, prime_implicant) in prime_implicants.iter().enumerate() { - print!("{i}"); - for &minterm in minterms { - if prime_implicant.covers(minterm) { - print!(" x "); - } else { - print!(" "); - } - } - println!(); - } -} - fn solve_prime_implicants_table(minterms: &[usize], prime_implicants: &[Cube]) -> Vec<Cube> { let mut table: HashSet<(usize, usize)> = (0..prime_implicants.len()) .cartesian_product(0..minterms.len()) @@ -254,7 +187,7 @@ fn solve_prime_implicants_table(minterms: &[usize], prime_implicants: &[Cube]) - fn minimize(n: usize, minterms: &[usize], maxterms: &[usize]) -> Vec<Cube> { let prime_implicants = minimize_prime_implicants(n, minterms, maxterms); - print_prime_implicants_table(n, minterms, &prime_implicants); + // print_prime_implicants_table(n, minterms, &prime_implicants); solve_prime_implicants_table(minterms, &prime_implicants) } @@ -431,36 +364,68 @@ fn cubes_to_wired_or(cubes: &[Cube], vars: &[&str]) -> Logic { } fn main() { - let vars = &["X4", "X3", "X2", "X1"]; - // let minterms = [0, 1, 2, 3, 4]; // Термы со значением 1 - // let maxterms = [5, 6, 7, 8, 9]; // Термы со значением 0 - // let minterms = [0, 1, 2, 3, 4, 5, 6, 7]; // Термы со значением 1 - // let maxterms = [9]; // Термы со значением 0 - let minterms = [0, 3, 4, 7]; // Термы со значением 1 - let maxterms = [1, 2, 5, 6]; // Термы со значением 0 - - let min_cubes = minimize(4, &minterms, &maxterms); - - println!("Итоговые термы: "); - for cube in min_cubes { - println!( - "{} -> {}", - cube_to_string(4, &cube), - cube_to_var_string(vars, &cube) - ); + let mut args = std::env::args().skip(1); + let chip_series_file_path = args.next().unwrap(); + let truth_table_file_path = args.next().unwrap(); + + // TODO: make a use of this + let _chip_series_file = std::fs::read_to_string(chip_series_file_path).unwrap(); + + let truth_table_file = std::fs::read_to_string(truth_table_file_path).unwrap(); + + // Parsing truth table + let mut truth_table_lines = truth_table_file.lines(); + + let truth_table_inputs = truth_table_lines + .next() + .map(|line| line.split_whitespace().collect_vec()) + .unwrap(); + let truth_table_outputs = truth_table_lines + .next() + .map(|line| line.split_whitespace().collect_vec()) + .unwrap(); + + let mut truth_table_minterms = vec![vec![]; truth_table_outputs.len()]; + let mut truth_table_maxterms = vec![vec![]; truth_table_outputs.len()]; + for line in truth_table_lines { + let (input, output) = line.split_once(char::is_whitespace).unwrap(); + if input.len() != truth_table_inputs.len() || output.len() != truth_table_outputs.len() { + panic!("Truth table is incorrect: invalid input/output size"); + } + + let input_term = usize::from_str_radix(input, 2).unwrap(); + for (i, ch) in output.chars().enumerate() { + match ch { + '1' => truth_table_minterms[i].push(input_term), + '0' => truth_table_maxterms[i].push(input_term), + '-' => (), + _ => panic!("Truth table is incorrect: invalid char in output section"), + } + } } - let cubes = minimize(4, &minterms, &maxterms); - let inv_cubes = minimize(4, &maxterms, &minterms); + for (output, (minterms, maxterms)) in truth_table_outputs + .into_iter() + .zip(truth_table_minterms.into_iter().zip(truth_table_maxterms)) + { + let cubes = minimize(truth_table_inputs.len(), &minterms, &maxterms); + let inv_cubes = minimize(truth_table_inputs.len(), &maxterms, &minterms); - println!("{}", cubes_to_dnf(&cubes, vars)); - println!("{}", cubes_to_nand(&cubes, vars)); - println!("{}", cubes_to_cnf(&inv_cubes, vars)); - println!("{}", cubes_to_nor(&inv_cubes, vars)); - println!("{}", cubes_to_wired_or(&inv_cubes, vars)); + println!("{output} = {}", cubes_to_dnf(&cubes, &truth_table_inputs)); + println!("{output} = {}", cubes_to_nand(&cubes, &truth_table_inputs)); + println!( + "{output} = {}", + cubes_to_cnf(&inv_cubes, &truth_table_inputs) + ); + println!( + "{output} = {}", + cubes_to_nor(&inv_cubes, &truth_table_inputs) + ); + println!( + "{output} = {}", + cubes_to_wired_or(&inv_cubes, &truth_table_inputs) + ); - // dbg!(cubes_to_dnf(&cubes, vars)); - // dbg!(cubes_to_nand(&cubes, vars)); - // dbg!(cubes_to_cnf(&inv_cubes, vars)); - // dbg!(cubes_to_nor(&inv_cubes, vars)); + println!(); + } } |