BoolExpr

Struct BoolExpr 

Source
pub struct BoolExpr { /* private fields */ }
Expand description

A boolean expression that can be manipulated programmatically

Uses Arc internally for efficient cloning. Provides a fluent method-based API and an expr! macro for clean syntax.

§Examples

§Examples

§Method-based API

use espresso_logic::BoolExpr;

let a = BoolExpr::variable("a");
let b = BoolExpr::variable("b");
let expr = a.and(&b).or(&a.not().and(&b.not()));

§Using operator overloading (requires explicit &)

use espresso_logic::BoolExpr;

let a = BoolExpr::variable("a");
let b = BoolExpr::variable("b");
let expr = &a * &b + &(&a).not() * &(&b).not();

Implementations§

Source§

impl BoolExpr

Source

pub fn variable(name: &str) -> Self

Create a variable expression with the given name

Examples found in repository?
examples/boolean_expressions.rs (line 13)
8fn main() -> std::io::Result<()> {
9    println!("=== Boolean Expression Examples ===\n");
10
11    // Example 1: Programmatic construction with expr! macro
12    println!("1. Programmatic Construction (using expr! macro):");
13    let a = BoolExpr::variable("a");
14    let b = BoolExpr::variable("b");
15    let _c = BoolExpr::variable("c");
16
17    // XOR function: a*~b + ~a*b - clean syntax!
18    let xor = expr!(a * !b + !a * b);
19    println!("   XOR = a*~b + ~a*b");
20    println!("   Variables: {:?}", xor.collect_variables());
21    let xor_cover = ExprCover::from_expr(xor);
22    println!(
23        "   Inputs: {}, Outputs: {}",
24        xor_cover.num_inputs(),
25        xor_cover.num_outputs()
26    );
27    println!();
28
29    // Example 2: Parsing from string
30    println!("2. Parsing from String:");
31    let parsed_expr = BoolExpr::parse("(a + b) * (c + d)").unwrap();
32    println!("   Expression: (a + b) * (c + d)");
33    println!("   Variables: {:?}", parsed_expr.collect_variables());
34    let parsed_cover = ExprCover::from_expr(parsed_expr);
35    println!(
36        "   Inputs: {}, Outputs: {}",
37        parsed_cover.num_inputs(),
38        parsed_cover.num_outputs()
39    );
40    println!();
41
42    // Example 3: Complex expression with negation
43    println!("3. Complex Expression with Negation:");
44    let complex = BoolExpr::parse("~(a * b) + (c * ~d)").unwrap();
45    println!("   Expression: ~(a * b) + (c * ~d)");
46    println!("   Variables: {:?}", complex.collect_variables());
47    println!();
48
49    // Example 4: Minimization
50    println!("4. Minimization Example:");
51    println!("   Original: a*b + a*b*c (redundant term)");
52
53    let a = BoolExpr::variable("a");
54    let b = BoolExpr::variable("b");
55    let c = BoolExpr::variable("c");
56    let redundant = expr!(a * b + a * b * c);
57
58    println!("   Before minimization:");
59    println!("      Variables: {:?}", redundant.collect_variables());
60
61    let mut redundant_cover = ExprCover::from_expr(redundant);
62    redundant_cover.minimize()?;
63    let minimized = redundant_cover.to_expr();
64
65    println!("   After minimization:");
66    println!("      Expression: {}", minimized);
67    println!();
68
69    // Example 5: XNOR function
70    println!("5. XNOR Function (equivalence):");
71    let a = BoolExpr::variable("a");
72    let b = BoolExpr::variable("b");
73    let xnor = expr!(a * b + !a * !b);
74
75    println!("   XNOR = a*b + ~a*~b");
76    println!("   Before minimize: {}", xnor);
77
78    let mut xnor_cover = ExprCover::from_expr(xnor);
79    xnor_cover.minimize()?;
80    let minimized_xnor = xnor_cover.to_expr();
81
82    println!("   After minimize:  {}", minimized_xnor);
83    println!();
84
85    // Example 6: Three-variable function
86    println!("6. Three-Variable Majority Function:");
87    let a = BoolExpr::variable("a");
88    let b = BoolExpr::variable("b");
89    let c = BoolExpr::variable("c");
90
91    // Majority function: true if at least 2 of 3 inputs are true
92    // For more complex expressions, the method API is clearer
93    let majority = a.and(&b).or(&b.and(&c)).or(&a.and(&c));
94    let mut majority_cover = ExprCover::from_expr(majority);
95
96    println!("   Majority = a*b + b*c + a*c");
97    println!("   Before minimize: {} cubes", majority_cover.num_cubes());
98
99    majority_cover.minimize()?;
100
101    println!("   After minimize:  {} cubes", majority_cover.num_cubes());
102    println!();
103
104    // Example 7: Converting to PLA format
105    println!("7. PLA Format Export:");
106    let a = BoolExpr::variable("a");
107    let b = BoolExpr::variable("b");
108    let simple = a.and(&b);
109    let simple_cover = ExprCover::from_expr(simple);
110
111    let pla_string = simple_cover.to_pla_string(espresso_logic::PLAType::F)?;
112    println!("   Expression: a * b");
113    println!("   PLA format:");
114    for line in pla_string.lines() {
115        println!("      {}", line);
116    }
117    println!();
118
119    // Example 8: Parsing with constants
120    println!("8. Expressions with Constants:");
121    let expr_with_const = BoolExpr::parse("a * 1 + 0 * b").unwrap();
122    println!("   Expression: a * 1 + 0 * b");
123    println!("   Variables: {:?}", expr_with_const.collect_variables());
124    println!();
125
126    // Example 9: De Morgan's laws in action
127    println!("9. De Morgan's Laws:");
128    let a = BoolExpr::variable("a");
129    let b = BoolExpr::variable("b");
130
131    let demorgan1 = expr!(!(a * b));
132    let cover1 = ExprCover::from_expr(demorgan1);
133    println!("   ~(a * b) has {} variables", cover1.num_inputs());
134
135    let demorgan2 = expr!(!(a + b));
136    let cover2 = ExprCover::from_expr(demorgan2);
137    println!("   ~(a + b) has {} variables", cover2.num_inputs());
138    println!();
139
140    // Example 10: Comparison - same logical function, different expressions
141    println!("10. Equivalent Expressions:");
142    let expr1 = BoolExpr::parse("a * b + a * c").unwrap();
143    let expr2 = BoolExpr::parse("a * (b + c)").unwrap();
144
145    let mut cover1 = ExprCover::from_expr(expr1);
146    let mut cover2 = ExprCover::from_expr(expr2);
147
148    println!("    Expression 1: a * b + a * c");
149    println!("    Expression 2: a * (b + c)");
150    println!("    Both have {} variables", cover1.num_inputs());
151
152    cover1.minimize()?;
153    cover2.minimize()?;
154
155    println!("    After minimization, they should be equivalent");
156    println!();
157
158    // Example 11: Iterating over cubes
159    println!("11. Cube Iteration:");
160    let expr = BoolExpr::parse("a * b + ~a * c").unwrap();
161    let cover = ExprCover::from_expr(expr);
162    println!("    Expression: a * b + ~a * c");
163    println!("    Cubes:");
164
165    for (i, (inputs, outputs)) in cover.cubes_iter().enumerate() {
166        print!("      Cube {}: inputs=[", i + 1);
167        for input in &inputs {
168            match input {
169                Some(true) => print!("1"),
170                Some(false) => print!("0"),
171                None => print!("-"),
172            }
173        }
174        print!("] outputs=[");
175        for output in &outputs {
176            match output {
177                Some(true) => print!("1"),
178                Some(false) => print!("0"),
179                None => print!("-"),
180            }
181        }
182        println!("]");
183    }
184    println!();
185
186    println!("=== Examples Complete ===");
187    Ok(())
188}
Source

pub fn constant(value: bool) -> Self

Create a constant expression (true or false)

Source

pub fn parse(input: &str) -> Result<Self, String>

Parse a boolean expression from a string

Supports standard boolean operators:

  • + for OR
  • * for AND
  • ~ or ! for NOT
  • Parentheses for grouping
  • Constants: 0, 1, true, false
Examples found in repository?
examples/boolean_expressions.rs (line 31)
8fn main() -> std::io::Result<()> {
9    println!("=== Boolean Expression Examples ===\n");
10
11    // Example 1: Programmatic construction with expr! macro
12    println!("1. Programmatic Construction (using expr! macro):");
13    let a = BoolExpr::variable("a");
14    let b = BoolExpr::variable("b");
15    let _c = BoolExpr::variable("c");
16
17    // XOR function: a*~b + ~a*b - clean syntax!
18    let xor = expr!(a * !b + !a * b);
19    println!("   XOR = a*~b + ~a*b");
20    println!("   Variables: {:?}", xor.collect_variables());
21    let xor_cover = ExprCover::from_expr(xor);
22    println!(
23        "   Inputs: {}, Outputs: {}",
24        xor_cover.num_inputs(),
25        xor_cover.num_outputs()
26    );
27    println!();
28
29    // Example 2: Parsing from string
30    println!("2. Parsing from String:");
31    let parsed_expr = BoolExpr::parse("(a + b) * (c + d)").unwrap();
32    println!("   Expression: (a + b) * (c + d)");
33    println!("   Variables: {:?}", parsed_expr.collect_variables());
34    let parsed_cover = ExprCover::from_expr(parsed_expr);
35    println!(
36        "   Inputs: {}, Outputs: {}",
37        parsed_cover.num_inputs(),
38        parsed_cover.num_outputs()
39    );
40    println!();
41
42    // Example 3: Complex expression with negation
43    println!("3. Complex Expression with Negation:");
44    let complex = BoolExpr::parse("~(a * b) + (c * ~d)").unwrap();
45    println!("   Expression: ~(a * b) + (c * ~d)");
46    println!("   Variables: {:?}", complex.collect_variables());
47    println!();
48
49    // Example 4: Minimization
50    println!("4. Minimization Example:");
51    println!("   Original: a*b + a*b*c (redundant term)");
52
53    let a = BoolExpr::variable("a");
54    let b = BoolExpr::variable("b");
55    let c = BoolExpr::variable("c");
56    let redundant = expr!(a * b + a * b * c);
57
58    println!("   Before minimization:");
59    println!("      Variables: {:?}", redundant.collect_variables());
60
61    let mut redundant_cover = ExprCover::from_expr(redundant);
62    redundant_cover.minimize()?;
63    let minimized = redundant_cover.to_expr();
64
65    println!("   After minimization:");
66    println!("      Expression: {}", minimized);
67    println!();
68
69    // Example 5: XNOR function
70    println!("5. XNOR Function (equivalence):");
71    let a = BoolExpr::variable("a");
72    let b = BoolExpr::variable("b");
73    let xnor = expr!(a * b + !a * !b);
74
75    println!("   XNOR = a*b + ~a*~b");
76    println!("   Before minimize: {}", xnor);
77
78    let mut xnor_cover = ExprCover::from_expr(xnor);
79    xnor_cover.minimize()?;
80    let minimized_xnor = xnor_cover.to_expr();
81
82    println!("   After minimize:  {}", minimized_xnor);
83    println!();
84
85    // Example 6: Three-variable function
86    println!("6. Three-Variable Majority Function:");
87    let a = BoolExpr::variable("a");
88    let b = BoolExpr::variable("b");
89    let c = BoolExpr::variable("c");
90
91    // Majority function: true if at least 2 of 3 inputs are true
92    // For more complex expressions, the method API is clearer
93    let majority = a.and(&b).or(&b.and(&c)).or(&a.and(&c));
94    let mut majority_cover = ExprCover::from_expr(majority);
95
96    println!("   Majority = a*b + b*c + a*c");
97    println!("   Before minimize: {} cubes", majority_cover.num_cubes());
98
99    majority_cover.minimize()?;
100
101    println!("   After minimize:  {} cubes", majority_cover.num_cubes());
102    println!();
103
104    // Example 7: Converting to PLA format
105    println!("7. PLA Format Export:");
106    let a = BoolExpr::variable("a");
107    let b = BoolExpr::variable("b");
108    let simple = a.and(&b);
109    let simple_cover = ExprCover::from_expr(simple);
110
111    let pla_string = simple_cover.to_pla_string(espresso_logic::PLAType::F)?;
112    println!("   Expression: a * b");
113    println!("   PLA format:");
114    for line in pla_string.lines() {
115        println!("      {}", line);
116    }
117    println!();
118
119    // Example 8: Parsing with constants
120    println!("8. Expressions with Constants:");
121    let expr_with_const = BoolExpr::parse("a * 1 + 0 * b").unwrap();
122    println!("   Expression: a * 1 + 0 * b");
123    println!("   Variables: {:?}", expr_with_const.collect_variables());
124    println!();
125
126    // Example 9: De Morgan's laws in action
127    println!("9. De Morgan's Laws:");
128    let a = BoolExpr::variable("a");
129    let b = BoolExpr::variable("b");
130
131    let demorgan1 = expr!(!(a * b));
132    let cover1 = ExprCover::from_expr(demorgan1);
133    println!("   ~(a * b) has {} variables", cover1.num_inputs());
134
135    let demorgan2 = expr!(!(a + b));
136    let cover2 = ExprCover::from_expr(demorgan2);
137    println!("   ~(a + b) has {} variables", cover2.num_inputs());
138    println!();
139
140    // Example 10: Comparison - same logical function, different expressions
141    println!("10. Equivalent Expressions:");
142    let expr1 = BoolExpr::parse("a * b + a * c").unwrap();
143    let expr2 = BoolExpr::parse("a * (b + c)").unwrap();
144
145    let mut cover1 = ExprCover::from_expr(expr1);
146    let mut cover2 = ExprCover::from_expr(expr2);
147
148    println!("    Expression 1: a * b + a * c");
149    println!("    Expression 2: a * (b + c)");
150    println!("    Both have {} variables", cover1.num_inputs());
151
152    cover1.minimize()?;
153    cover2.minimize()?;
154
155    println!("    After minimization, they should be equivalent");
156    println!();
157
158    // Example 11: Iterating over cubes
159    println!("11. Cube Iteration:");
160    let expr = BoolExpr::parse("a * b + ~a * c").unwrap();
161    let cover = ExprCover::from_expr(expr);
162    println!("    Expression: a * b + ~a * c");
163    println!("    Cubes:");
164
165    for (i, (inputs, outputs)) in cover.cubes_iter().enumerate() {
166        print!("      Cube {}: inputs=[", i + 1);
167        for input in &inputs {
168            match input {
169                Some(true) => print!("1"),
170                Some(false) => print!("0"),
171                None => print!("-"),
172            }
173        }
174        print!("] outputs=[");
175        for output in &outputs {
176            match output {
177                Some(true) => print!("1"),
178                Some(false) => print!("0"),
179                None => print!("-"),
180            }
181        }
182        println!("]");
183    }
184    println!();
185
186    println!("=== Examples Complete ===");
187    Ok(())
188}
Source

pub fn collect_variables(&self) -> BTreeSet<Arc<str>>

Collect all variables used in this expression in alphabetical order

Returns a BTreeSet which maintains variables in sorted order. This ordering is used when converting to covers for minimization.

Examples found in repository?
examples/boolean_expressions.rs (line 20)
8fn main() -> std::io::Result<()> {
9    println!("=== Boolean Expression Examples ===\n");
10
11    // Example 1: Programmatic construction with expr! macro
12    println!("1. Programmatic Construction (using expr! macro):");
13    let a = BoolExpr::variable("a");
14    let b = BoolExpr::variable("b");
15    let _c = BoolExpr::variable("c");
16
17    // XOR function: a*~b + ~a*b - clean syntax!
18    let xor = expr!(a * !b + !a * b);
19    println!("   XOR = a*~b + ~a*b");
20    println!("   Variables: {:?}", xor.collect_variables());
21    let xor_cover = ExprCover::from_expr(xor);
22    println!(
23        "   Inputs: {}, Outputs: {}",
24        xor_cover.num_inputs(),
25        xor_cover.num_outputs()
26    );
27    println!();
28
29    // Example 2: Parsing from string
30    println!("2. Parsing from String:");
31    let parsed_expr = BoolExpr::parse("(a + b) * (c + d)").unwrap();
32    println!("   Expression: (a + b) * (c + d)");
33    println!("   Variables: {:?}", parsed_expr.collect_variables());
34    let parsed_cover = ExprCover::from_expr(parsed_expr);
35    println!(
36        "   Inputs: {}, Outputs: {}",
37        parsed_cover.num_inputs(),
38        parsed_cover.num_outputs()
39    );
40    println!();
41
42    // Example 3: Complex expression with negation
43    println!("3. Complex Expression with Negation:");
44    let complex = BoolExpr::parse("~(a * b) + (c * ~d)").unwrap();
45    println!("   Expression: ~(a * b) + (c * ~d)");
46    println!("   Variables: {:?}", complex.collect_variables());
47    println!();
48
49    // Example 4: Minimization
50    println!("4. Minimization Example:");
51    println!("   Original: a*b + a*b*c (redundant term)");
52
53    let a = BoolExpr::variable("a");
54    let b = BoolExpr::variable("b");
55    let c = BoolExpr::variable("c");
56    let redundant = expr!(a * b + a * b * c);
57
58    println!("   Before minimization:");
59    println!("      Variables: {:?}", redundant.collect_variables());
60
61    let mut redundant_cover = ExprCover::from_expr(redundant);
62    redundant_cover.minimize()?;
63    let minimized = redundant_cover.to_expr();
64
65    println!("   After minimization:");
66    println!("      Expression: {}", minimized);
67    println!();
68
69    // Example 5: XNOR function
70    println!("5. XNOR Function (equivalence):");
71    let a = BoolExpr::variable("a");
72    let b = BoolExpr::variable("b");
73    let xnor = expr!(a * b + !a * !b);
74
75    println!("   XNOR = a*b + ~a*~b");
76    println!("   Before minimize: {}", xnor);
77
78    let mut xnor_cover = ExprCover::from_expr(xnor);
79    xnor_cover.minimize()?;
80    let minimized_xnor = xnor_cover.to_expr();
81
82    println!("   After minimize:  {}", minimized_xnor);
83    println!();
84
85    // Example 6: Three-variable function
86    println!("6. Three-Variable Majority Function:");
87    let a = BoolExpr::variable("a");
88    let b = BoolExpr::variable("b");
89    let c = BoolExpr::variable("c");
90
91    // Majority function: true if at least 2 of 3 inputs are true
92    // For more complex expressions, the method API is clearer
93    let majority = a.and(&b).or(&b.and(&c)).or(&a.and(&c));
94    let mut majority_cover = ExprCover::from_expr(majority);
95
96    println!("   Majority = a*b + b*c + a*c");
97    println!("   Before minimize: {} cubes", majority_cover.num_cubes());
98
99    majority_cover.minimize()?;
100
101    println!("   After minimize:  {} cubes", majority_cover.num_cubes());
102    println!();
103
104    // Example 7: Converting to PLA format
105    println!("7. PLA Format Export:");
106    let a = BoolExpr::variable("a");
107    let b = BoolExpr::variable("b");
108    let simple = a.and(&b);
109    let simple_cover = ExprCover::from_expr(simple);
110
111    let pla_string = simple_cover.to_pla_string(espresso_logic::PLAType::F)?;
112    println!("   Expression: a * b");
113    println!("   PLA format:");
114    for line in pla_string.lines() {
115        println!("      {}", line);
116    }
117    println!();
118
119    // Example 8: Parsing with constants
120    println!("8. Expressions with Constants:");
121    let expr_with_const = BoolExpr::parse("a * 1 + 0 * b").unwrap();
122    println!("   Expression: a * 1 + 0 * b");
123    println!("   Variables: {:?}", expr_with_const.collect_variables());
124    println!();
125
126    // Example 9: De Morgan's laws in action
127    println!("9. De Morgan's Laws:");
128    let a = BoolExpr::variable("a");
129    let b = BoolExpr::variable("b");
130
131    let demorgan1 = expr!(!(a * b));
132    let cover1 = ExprCover::from_expr(demorgan1);
133    println!("   ~(a * b) has {} variables", cover1.num_inputs());
134
135    let demorgan2 = expr!(!(a + b));
136    let cover2 = ExprCover::from_expr(demorgan2);
137    println!("   ~(a + b) has {} variables", cover2.num_inputs());
138    println!();
139
140    // Example 10: Comparison - same logical function, different expressions
141    println!("10. Equivalent Expressions:");
142    let expr1 = BoolExpr::parse("a * b + a * c").unwrap();
143    let expr2 = BoolExpr::parse("a * (b + c)").unwrap();
144
145    let mut cover1 = ExprCover::from_expr(expr1);
146    let mut cover2 = ExprCover::from_expr(expr2);
147
148    println!("    Expression 1: a * b + a * c");
149    println!("    Expression 2: a * (b + c)");
150    println!("    Both have {} variables", cover1.num_inputs());
151
152    cover1.minimize()?;
153    cover2.minimize()?;
154
155    println!("    After minimization, they should be equivalent");
156    println!();
157
158    // Example 11: Iterating over cubes
159    println!("11. Cube Iteration:");
160    let expr = BoolExpr::parse("a * b + ~a * c").unwrap();
161    let cover = ExprCover::from_expr(expr);
162    println!("    Expression: a * b + ~a * c");
163    println!("    Cubes:");
164
165    for (i, (inputs, outputs)) in cover.cubes_iter().enumerate() {
166        print!("      Cube {}: inputs=[", i + 1);
167        for input in &inputs {
168            match input {
169                Some(true) => print!("1"),
170                Some(false) => print!("0"),
171                None => print!("-"),
172            }
173        }
174        print!("] outputs=[");
175        for output in &outputs {
176            match output {
177                Some(true) => print!("1"),
178                Some(false) => print!("0"),
179                None => print!("-"),
180            }
181        }
182        println!("]");
183    }
184    println!();
185
186    println!("=== Examples Complete ===");
187    Ok(())
188}
Source

pub fn and(&self, other: &BoolExpr) -> BoolExpr

Logical AND: create a new expression that is the conjunction of this and another

Examples found in repository?
examples/boolean_expressions.rs (line 93)
8fn main() -> std::io::Result<()> {
9    println!("=== Boolean Expression Examples ===\n");
10
11    // Example 1: Programmatic construction with expr! macro
12    println!("1. Programmatic Construction (using expr! macro):");
13    let a = BoolExpr::variable("a");
14    let b = BoolExpr::variable("b");
15    let _c = BoolExpr::variable("c");
16
17    // XOR function: a*~b + ~a*b - clean syntax!
18    let xor = expr!(a * !b + !a * b);
19    println!("   XOR = a*~b + ~a*b");
20    println!("   Variables: {:?}", xor.collect_variables());
21    let xor_cover = ExprCover::from_expr(xor);
22    println!(
23        "   Inputs: {}, Outputs: {}",
24        xor_cover.num_inputs(),
25        xor_cover.num_outputs()
26    );
27    println!();
28
29    // Example 2: Parsing from string
30    println!("2. Parsing from String:");
31    let parsed_expr = BoolExpr::parse("(a + b) * (c + d)").unwrap();
32    println!("   Expression: (a + b) * (c + d)");
33    println!("   Variables: {:?}", parsed_expr.collect_variables());
34    let parsed_cover = ExprCover::from_expr(parsed_expr);
35    println!(
36        "   Inputs: {}, Outputs: {}",
37        parsed_cover.num_inputs(),
38        parsed_cover.num_outputs()
39    );
40    println!();
41
42    // Example 3: Complex expression with negation
43    println!("3. Complex Expression with Negation:");
44    let complex = BoolExpr::parse("~(a * b) + (c * ~d)").unwrap();
45    println!("   Expression: ~(a * b) + (c * ~d)");
46    println!("   Variables: {:?}", complex.collect_variables());
47    println!();
48
49    // Example 4: Minimization
50    println!("4. Minimization Example:");
51    println!("   Original: a*b + a*b*c (redundant term)");
52
53    let a = BoolExpr::variable("a");
54    let b = BoolExpr::variable("b");
55    let c = BoolExpr::variable("c");
56    let redundant = expr!(a * b + a * b * c);
57
58    println!("   Before minimization:");
59    println!("      Variables: {:?}", redundant.collect_variables());
60
61    let mut redundant_cover = ExprCover::from_expr(redundant);
62    redundant_cover.minimize()?;
63    let minimized = redundant_cover.to_expr();
64
65    println!("   After minimization:");
66    println!("      Expression: {}", minimized);
67    println!();
68
69    // Example 5: XNOR function
70    println!("5. XNOR Function (equivalence):");
71    let a = BoolExpr::variable("a");
72    let b = BoolExpr::variable("b");
73    let xnor = expr!(a * b + !a * !b);
74
75    println!("   XNOR = a*b + ~a*~b");
76    println!("   Before minimize: {}", xnor);
77
78    let mut xnor_cover = ExprCover::from_expr(xnor);
79    xnor_cover.minimize()?;
80    let minimized_xnor = xnor_cover.to_expr();
81
82    println!("   After minimize:  {}", minimized_xnor);
83    println!();
84
85    // Example 6: Three-variable function
86    println!("6. Three-Variable Majority Function:");
87    let a = BoolExpr::variable("a");
88    let b = BoolExpr::variable("b");
89    let c = BoolExpr::variable("c");
90
91    // Majority function: true if at least 2 of 3 inputs are true
92    // For more complex expressions, the method API is clearer
93    let majority = a.and(&b).or(&b.and(&c)).or(&a.and(&c));
94    let mut majority_cover = ExprCover::from_expr(majority);
95
96    println!("   Majority = a*b + b*c + a*c");
97    println!("   Before minimize: {} cubes", majority_cover.num_cubes());
98
99    majority_cover.minimize()?;
100
101    println!("   After minimize:  {} cubes", majority_cover.num_cubes());
102    println!();
103
104    // Example 7: Converting to PLA format
105    println!("7. PLA Format Export:");
106    let a = BoolExpr::variable("a");
107    let b = BoolExpr::variable("b");
108    let simple = a.and(&b);
109    let simple_cover = ExprCover::from_expr(simple);
110
111    let pla_string = simple_cover.to_pla_string(espresso_logic::PLAType::F)?;
112    println!("   Expression: a * b");
113    println!("   PLA format:");
114    for line in pla_string.lines() {
115        println!("      {}", line);
116    }
117    println!();
118
119    // Example 8: Parsing with constants
120    println!("8. Expressions with Constants:");
121    let expr_with_const = BoolExpr::parse("a * 1 + 0 * b").unwrap();
122    println!("   Expression: a * 1 + 0 * b");
123    println!("   Variables: {:?}", expr_with_const.collect_variables());
124    println!();
125
126    // Example 9: De Morgan's laws in action
127    println!("9. De Morgan's Laws:");
128    let a = BoolExpr::variable("a");
129    let b = BoolExpr::variable("b");
130
131    let demorgan1 = expr!(!(a * b));
132    let cover1 = ExprCover::from_expr(demorgan1);
133    println!("   ~(a * b) has {} variables", cover1.num_inputs());
134
135    let demorgan2 = expr!(!(a + b));
136    let cover2 = ExprCover::from_expr(demorgan2);
137    println!("   ~(a + b) has {} variables", cover2.num_inputs());
138    println!();
139
140    // Example 10: Comparison - same logical function, different expressions
141    println!("10. Equivalent Expressions:");
142    let expr1 = BoolExpr::parse("a * b + a * c").unwrap();
143    let expr2 = BoolExpr::parse("a * (b + c)").unwrap();
144
145    let mut cover1 = ExprCover::from_expr(expr1);
146    let mut cover2 = ExprCover::from_expr(expr2);
147
148    println!("    Expression 1: a * b + a * c");
149    println!("    Expression 2: a * (b + c)");
150    println!("    Both have {} variables", cover1.num_inputs());
151
152    cover1.minimize()?;
153    cover2.minimize()?;
154
155    println!("    After minimization, they should be equivalent");
156    println!();
157
158    // Example 11: Iterating over cubes
159    println!("11. Cube Iteration:");
160    let expr = BoolExpr::parse("a * b + ~a * c").unwrap();
161    let cover = ExprCover::from_expr(expr);
162    println!("    Expression: a * b + ~a * c");
163    println!("    Cubes:");
164
165    for (i, (inputs, outputs)) in cover.cubes_iter().enumerate() {
166        print!("      Cube {}: inputs=[", i + 1);
167        for input in &inputs {
168            match input {
169                Some(true) => print!("1"),
170                Some(false) => print!("0"),
171                None => print!("-"),
172            }
173        }
174        print!("] outputs=[");
175        for output in &outputs {
176            match output {
177                Some(true) => print!("1"),
178                Some(false) => print!("0"),
179                None => print!("-"),
180            }
181        }
182        println!("]");
183    }
184    println!();
185
186    println!("=== Examples Complete ===");
187    Ok(())
188}
Source

pub fn or(&self, other: &BoolExpr) -> BoolExpr

Logical OR: create a new expression that is the disjunction of this and another

Examples found in repository?
examples/boolean_expressions.rs (line 93)
8fn main() -> std::io::Result<()> {
9    println!("=== Boolean Expression Examples ===\n");
10
11    // Example 1: Programmatic construction with expr! macro
12    println!("1. Programmatic Construction (using expr! macro):");
13    let a = BoolExpr::variable("a");
14    let b = BoolExpr::variable("b");
15    let _c = BoolExpr::variable("c");
16
17    // XOR function: a*~b + ~a*b - clean syntax!
18    let xor = expr!(a * !b + !a * b);
19    println!("   XOR = a*~b + ~a*b");
20    println!("   Variables: {:?}", xor.collect_variables());
21    let xor_cover = ExprCover::from_expr(xor);
22    println!(
23        "   Inputs: {}, Outputs: {}",
24        xor_cover.num_inputs(),
25        xor_cover.num_outputs()
26    );
27    println!();
28
29    // Example 2: Parsing from string
30    println!("2. Parsing from String:");
31    let parsed_expr = BoolExpr::parse("(a + b) * (c + d)").unwrap();
32    println!("   Expression: (a + b) * (c + d)");
33    println!("   Variables: {:?}", parsed_expr.collect_variables());
34    let parsed_cover = ExprCover::from_expr(parsed_expr);
35    println!(
36        "   Inputs: {}, Outputs: {}",
37        parsed_cover.num_inputs(),
38        parsed_cover.num_outputs()
39    );
40    println!();
41
42    // Example 3: Complex expression with negation
43    println!("3. Complex Expression with Negation:");
44    let complex = BoolExpr::parse("~(a * b) + (c * ~d)").unwrap();
45    println!("   Expression: ~(a * b) + (c * ~d)");
46    println!("   Variables: {:?}", complex.collect_variables());
47    println!();
48
49    // Example 4: Minimization
50    println!("4. Minimization Example:");
51    println!("   Original: a*b + a*b*c (redundant term)");
52
53    let a = BoolExpr::variable("a");
54    let b = BoolExpr::variable("b");
55    let c = BoolExpr::variable("c");
56    let redundant = expr!(a * b + a * b * c);
57
58    println!("   Before minimization:");
59    println!("      Variables: {:?}", redundant.collect_variables());
60
61    let mut redundant_cover = ExprCover::from_expr(redundant);
62    redundant_cover.minimize()?;
63    let minimized = redundant_cover.to_expr();
64
65    println!("   After minimization:");
66    println!("      Expression: {}", minimized);
67    println!();
68
69    // Example 5: XNOR function
70    println!("5. XNOR Function (equivalence):");
71    let a = BoolExpr::variable("a");
72    let b = BoolExpr::variable("b");
73    let xnor = expr!(a * b + !a * !b);
74
75    println!("   XNOR = a*b + ~a*~b");
76    println!("   Before minimize: {}", xnor);
77
78    let mut xnor_cover = ExprCover::from_expr(xnor);
79    xnor_cover.minimize()?;
80    let minimized_xnor = xnor_cover.to_expr();
81
82    println!("   After minimize:  {}", minimized_xnor);
83    println!();
84
85    // Example 6: Three-variable function
86    println!("6. Three-Variable Majority Function:");
87    let a = BoolExpr::variable("a");
88    let b = BoolExpr::variable("b");
89    let c = BoolExpr::variable("c");
90
91    // Majority function: true if at least 2 of 3 inputs are true
92    // For more complex expressions, the method API is clearer
93    let majority = a.and(&b).or(&b.and(&c)).or(&a.and(&c));
94    let mut majority_cover = ExprCover::from_expr(majority);
95
96    println!("   Majority = a*b + b*c + a*c");
97    println!("   Before minimize: {} cubes", majority_cover.num_cubes());
98
99    majority_cover.minimize()?;
100
101    println!("   After minimize:  {} cubes", majority_cover.num_cubes());
102    println!();
103
104    // Example 7: Converting to PLA format
105    println!("7. PLA Format Export:");
106    let a = BoolExpr::variable("a");
107    let b = BoolExpr::variable("b");
108    let simple = a.and(&b);
109    let simple_cover = ExprCover::from_expr(simple);
110
111    let pla_string = simple_cover.to_pla_string(espresso_logic::PLAType::F)?;
112    println!("   Expression: a * b");
113    println!("   PLA format:");
114    for line in pla_string.lines() {
115        println!("      {}", line);
116    }
117    println!();
118
119    // Example 8: Parsing with constants
120    println!("8. Expressions with Constants:");
121    let expr_with_const = BoolExpr::parse("a * 1 + 0 * b").unwrap();
122    println!("   Expression: a * 1 + 0 * b");
123    println!("   Variables: {:?}", expr_with_const.collect_variables());
124    println!();
125
126    // Example 9: De Morgan's laws in action
127    println!("9. De Morgan's Laws:");
128    let a = BoolExpr::variable("a");
129    let b = BoolExpr::variable("b");
130
131    let demorgan1 = expr!(!(a * b));
132    let cover1 = ExprCover::from_expr(demorgan1);
133    println!("   ~(a * b) has {} variables", cover1.num_inputs());
134
135    let demorgan2 = expr!(!(a + b));
136    let cover2 = ExprCover::from_expr(demorgan2);
137    println!("   ~(a + b) has {} variables", cover2.num_inputs());
138    println!();
139
140    // Example 10: Comparison - same logical function, different expressions
141    println!("10. Equivalent Expressions:");
142    let expr1 = BoolExpr::parse("a * b + a * c").unwrap();
143    let expr2 = BoolExpr::parse("a * (b + c)").unwrap();
144
145    let mut cover1 = ExprCover::from_expr(expr1);
146    let mut cover2 = ExprCover::from_expr(expr2);
147
148    println!("    Expression 1: a * b + a * c");
149    println!("    Expression 2: a * (b + c)");
150    println!("    Both have {} variables", cover1.num_inputs());
151
152    cover1.minimize()?;
153    cover2.minimize()?;
154
155    println!("    After minimization, they should be equivalent");
156    println!();
157
158    // Example 11: Iterating over cubes
159    println!("11. Cube Iteration:");
160    let expr = BoolExpr::parse("a * b + ~a * c").unwrap();
161    let cover = ExprCover::from_expr(expr);
162    println!("    Expression: a * b + ~a * c");
163    println!("    Cubes:");
164
165    for (i, (inputs, outputs)) in cover.cubes_iter().enumerate() {
166        print!("      Cube {}: inputs=[", i + 1);
167        for input in &inputs {
168            match input {
169                Some(true) => print!("1"),
170                Some(false) => print!("0"),
171                None => print!("-"),
172            }
173        }
174        print!("] outputs=[");
175        for output in &outputs {
176            match output {
177                Some(true) => print!("1"),
178                Some(false) => print!("0"),
179                None => print!("-"),
180            }
181        }
182        println!("]");
183    }
184    println!();
185
186    println!("=== Examples Complete ===");
187    Ok(())
188}
Source

pub fn not(&self) -> BoolExpr

Logical NOT: create a new expression that is the negation of this one

Source

pub fn minimize(self) -> Result<BoolExpr>

Minimize this boolean expression using Espresso

This is a convenience method that creates an ExprCover, minimizes it, and returns the minimized expression.

§Examples
use espresso_logic::{BoolExpr, expr};

let a = BoolExpr::variable("a");
let b = BoolExpr::variable("b");
let c = BoolExpr::variable("c");

// Redundant expression
let expr = expr!(a * b + a * b * c);

// Minimize it
let minimized = expr.minimize()?;

// minimized should be simpler (just a * b)

Trait Implementations§

Source§

impl Add for &BoolExpr

Logical OR operator for references: &a + &b

Source§

type Output = BoolExpr

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &BoolExpr) -> BoolExpr

Performs the + operation. Read more
Source§

impl Add for BoolExpr

Logical OR operator: a + b (delegates to reference version)

Source§

type Output = BoolExpr

The resulting type after applying the + operator.
Source§

fn add(self, rhs: BoolExpr) -> BoolExpr

Performs the + operation. Read more
Source§

impl Clone for BoolExpr

Source§

fn clone(&self) -> BoolExpr

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for BoolExpr

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for BoolExpr

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Mul for &BoolExpr

Logical AND operator for references: &a * &b

Source§

type Output = BoolExpr

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &BoolExpr) -> BoolExpr

Performs the * operation. Read more
Source§

impl Mul for BoolExpr

Logical AND operator: a * b (delegates to reference version)

Source§

type Output = BoolExpr

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: BoolExpr) -> BoolExpr

Performs the * operation. Read more
Source§

impl Not for &BoolExpr

Logical NOT operator for references: !&a

Source§

type Output = BoolExpr

The resulting type after applying the ! operator.
Source§

fn not(self) -> BoolExpr

Performs the unary ! operation. Read more
Source§

impl Not for BoolExpr

Logical NOT operator: !a (delegates to reference version)

Source§

type Output = BoolExpr

The resulting type after applying the ! operator.
Source§

fn not(self) -> BoolExpr

Performs the unary ! operation. Read more
Source§

impl PartialEq for BoolExpr

Source§

fn eq(&self, other: &BoolExpr) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for BoolExpr

Source§

impl StructuralPartialEq for BoolExpr

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.