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
impl BoolExpr
Sourcepub fn variable(name: &str) -> Self
pub fn variable(name: &str) -> Self
Create a variable expression with the given name
Examples found in repository?
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}Sourcepub fn parse(input: &str) -> Result<Self, String>
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?
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}Sourcepub fn collect_variables(&self) -> BTreeSet<Arc<str>>
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?
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}Sourcepub fn and(&self, other: &BoolExpr) -> BoolExpr
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?
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}Sourcepub fn or(&self, other: &BoolExpr) -> BoolExpr
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?
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}Sourcepub fn not(&self) -> BoolExpr
pub fn not(&self) -> BoolExpr
Logical NOT: create a new expression that is the negation of this one
Sourcepub fn minimize(self) -> Result<BoolExpr>
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)