espresso_logic/cover/
conversions.rs1use super::cubes::{Cube, CubeType};
7use super::labels::LabelManager;
8use super::Cover;
9use super::CoverType;
10use std::collections::BTreeSet;
11use std::fmt;
12use std::sync::Arc;
13
14impl super::pla::PLASerialisable for Cover {
16 type CubesIter<'a> = std::slice::Iter<'a, Cube>;
17
18 fn num_inputs(&self) -> usize {
19 self.num_inputs
20 }
21
22 fn num_outputs(&self) -> usize {
23 self.num_outputs
24 }
25
26 fn internal_cubes_iter(&self) -> Self::CubesIter<'_> {
27 self.cubes.iter()
28 }
29
30 fn get_input_labels(&self) -> Option<&[Arc<str>]> {
31 if self.input_labels.is_empty() {
32 None
33 } else {
34 Some(self.input_labels.as_slice())
35 }
36 }
37
38 fn get_output_labels(&self) -> Option<&[Arc<str>]> {
39 if self.output_labels.is_empty() {
40 None
41 } else {
42 Some(self.output_labels.as_slice())
43 }
44 }
45
46 fn create_from_pla_parts(
47 num_inputs: usize,
48 num_outputs: usize,
49 input_labels: Vec<Arc<str>>,
50 output_labels: Vec<Arc<str>>,
51 cubes: Vec<Cube>,
52 cover_type: CoverType,
53 ) -> Self {
54 Cover {
55 num_inputs,
56 num_outputs,
57 input_labels: LabelManager::from_labels(input_labels),
58 output_labels: LabelManager::from_labels(output_labels),
59 cubes,
60 cover_type,
61 }
62 }
63}
64
65impl From<crate::expression::BoolExpr> for Cover {
82 fn from(expr: crate::expression::BoolExpr) -> Self {
83 let mut cover = Cover::new(CoverType::F);
84 cover
85 .add_expr(&expr, "out")
86 .expect("Adding expression to new cover should not fail");
87 cover
88 }
89}
90
91impl From<&crate::expression::BoolExpr> for Cover {
108 fn from(expr: &crate::expression::BoolExpr) -> Self {
109 let dnf = crate::cover::dnf::Dnf::from(expr);
111 let cubes = dnf.cubes();
112
113 let mut all_vars = BTreeSet::new();
115 for product_term in cubes {
116 for var in product_term.keys() {
117 all_vars.insert(Arc::clone(var));
118 }
119 }
120
121 let var_vec: Vec<Arc<str>> = all_vars.into_iter().collect();
123 let var_refs: Vec<&str> = var_vec.iter().map(|s| s.as_ref()).collect();
124 let mut cover = Cover::with_labels(CoverType::F, &var_refs, &["out"]);
125
126 for product_term in cubes {
128 let mut inputs = vec![None; cover.num_inputs()];
129 for (var, &polarity) in product_term {
130 if let Some(idx) = cover.input_labels.find_position(var) {
131 inputs[idx] = Some(polarity);
132 }
133 }
134
135 let outputs = vec![true; cover.num_outputs()];
136 cover.cubes.push(Cube::new(&inputs, &outputs, CubeType::F));
137 }
138
139 cover
140 }
141}
142
143impl fmt::Debug for Cover {
144 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145 f.debug_struct("Cover")
146 .field("num_inputs", &self.num_inputs)
147 .field("num_outputs", &self.num_outputs)
148 .field("cover_type", &self.cover_type)
149 .field("num_cubes", &self.num_cubes())
150 .field("input_labels", &self.input_labels)
151 .field("output_labels", &self.output_labels)
152 .finish()
153 }
154}