summaryrefslogtreecommitdiffstats
path: root/vendor/quine-mc_cluskey/README.md
blob: cf562665a678bcb04971ffc349950650c1641f75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
[![Clippy Linting Result](https://clippy.bashy.io/github/oli-obk/quine-mc_cluskey/master/badge.svg)](https://clippy.bashy.io/github/oli-obk/quine-mc_cluskey/master/log)
[![Current Version](http://meritbadge.herokuapp.com/quine-mc_cluskey)](https://crates.io/crates/quine-mc_cluskey)
[![Build Status](https://travis-ci.org/oli-obk/quine-mc_cluskey.svg?branch=master)](https://travis-ci.org/oli-obk/quine-mc_cluskey)

An algorithm to automatically minimize boolean expressions.

# Example

```rust
extern crate quine_mc_cluskey;

use quine_mc_cluskey::*;
use quine_mc_cluskey::Bool::{And, Or, Not, True, False};

fn main() {
    // !false => true
    assert_eq!(
        Not(Box::new(False)).simplify(),
        vec![True]
    );

    // a && (b || a) => a
    assert_eq!(
        And(vec![Bool::Term(0),
        Or(vec![Bool::Term(1), Bool::Term(0)])]).simplify(), vec![Bool::Term(0)]
    );
}
```

# Obtaining a minimal "and of or" form

Sometimes an expression of the form `a && (b || c)` is shorter than the `a && b || a && c` form.
We can simply negate the original expression and negate all the resulting simplified expressions to obtain that form.

```rust
extern crate quine_mc_cluskey;
use quine_mc_cluskey::Bool;

fn main() {
    let a: Bool = Bool::And(vec![Bool::True, Bool::True]);
    let simplified: Vec<Bool> = Bool::Not(Box::new(a)).simplify()
        .iter().map(simple_negate).collect();
}

fn simple_negate(b: &Bool) -> Bool {
    use quine_mc_cluskey::Bool::*;
    let b = b.clone();

    match b {
        True => False,
        False => True,
        t @ Term(_) => Not(Box::new(t)),
        And(mut v) => {
            for el in &mut v {
                *el = simple_negate(el);
            }
            Or(v)
        },
        Or(mut v) => {
            for el in &mut v {
                *el = simple_negate(el);
            }
            And(v)
        },
        Not(inner) => *inner,
    }
}
```