diff --git a/src/lib.rs b/src/lib.rs index f857a88..1950ed5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,6 +82,70 @@ pub fn find_groups(func: &FunctionSpec, vars: &[Variable], typ: Output) -> Vec(func: &FunctionSpec, vars: &[Variable], typ: Output, blocks: &'a [Vec<(Variable, Output)>]) -> Vec<&'a [(Variable, Output)]> { + assert_eq!(func.len(), 2usize.pow(vars.len() as u32)); + + let block_masks = blocks.iter().map(|x| &**x) + .map(block_to_mask) + .collect::>(); + + let mut prime = vec![false; blocks.len()]; + 'input: for input in 0..func.len() { + if func[input] != typ { + continue; + } + let mut matched = None; + for (i, (mask, inv_mask)) in block_masks.iter().enumerate() { + if input | mask == input && input & inv_mask == input { + if matched.is_none() { + matched = Some(i); + } else { + continue 'input; + } + } + } + if let Some(i) = matched { + prime[i] = true; + } + } + prime.into_iter().enumerate().filter(|&(_, prime)| prime).map(|(i, _)| &*blocks[i]).collect() +} + +/// a ⊆ b fn subset_of(a: &[T], b: &[T]) -> bool { a.iter().all(|x| b.contains(x)) +} + +fn block_to_mask(block: &[(Variable, Output)]) -> (Variable, Variable) { + let mut mask = 0; + let mut inv_mask = !0; + for &(var, out) in block { + mask |= if out == One { var } else { 0 }; + inv_mask ^= if out == Zero { var } else { 0 }; + } + (mask, inv_mask) +} + +pub fn print_implicate(vars: &[(Variable, Output)]) -> String { + let mut s = String::new(); + for i in 0..vars.len() { + let (var, out) = vars[i]; + if out == One { + s += "~"; + } + s += print_var(var); + if i != vars.len() - 1 { + s += " v "; + } + } + s +} + +fn print_var(var: Variable) -> &'static str { + match var { + A => "a", + B => "b", + C => "c", + _ => "?" + } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 8110cdf..ebebea9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,13 @@ use kv::Output::*; fn main() { let function = vec![0, 0, 1, 0, 0, 1, 1, 1].into_iter().map(Into::into).collect(); let groups = find_groups(&function, &mut [A, B, C], Zero); - for x in groups { - println!("{:?}", x); + println!("all:"); + for x in &groups { + println!("{}", print_implicate(x)); + } + println!("prime:"); + let prime = find_prime(&function, &mut [A, B, C], Zero, &groups); + for x in prime { + println!("{}", print_implicate(&x)); } }