logical_expression_pest_parser/
truth_table.rs1use crate::ast::Expression;
2use std::collections::HashMap;
3use std::fmt::{Display, Formatter};
4
5#[derive(Debug)]
7pub struct TruthTableRow {
8 pub values: Vec<bool>,
10 pub result: bool,
12}
13
14#[derive(Debug)]
16pub struct TruthTable {
17 pub variables: Vec<char>,
19 pub rows: Vec<TruthTableRow>,
21}
22
23impl Display for TruthTableRow {
24 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
26 write!(f, "|")?;
27 for &value in &self.values {
28 write!(f, " {} |", if value { '1' } else { '0' })?;
29 }
30 write!(f, " {} |", if self.result { '1' } else { '0' })?;
31
32 Ok(())
33 }
34}
35
36impl Display for TruthTable {
37 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
39 write!(f, "|")?;
40 for variable in &self.variables {
41 write!(f, " {} |", variable)?;
42 }
43 writeln!(f, " Output |")?;
44
45 write!(f, "|")?;
46 for _ in &self.variables {
47 write!(f, "---|")?;
48 }
49 writeln!(f, "--------|")?;
50
51 for row in &self.rows {
52 writeln!(f, "{}", row)?;
53 }
54
55 Ok(())
56 }
57}
58impl From<&Expression> for TruthTable {
59 fn from(expression: &Expression) -> Self {
66 let variables = expression.variables();
67
68 let variables_length = variables.len();
69 let rows_length = if variables_length == 0 {
70 0
71 } else {
72 2_usize.pow(variables_length as u32)
73 };
74
75 let mut rows: Vec<TruthTableRow> = Vec::with_capacity(rows_length);
76 for row_index in 0..rows_length {
77 let mut values = Vec::with_capacity(variables_length);
78 let mut idens_values = HashMap::with_capacity(variables_length);
79
80 for (identifier_index, &identifier) in variables.iter().enumerate() {
81 let value = row_index / 2_usize.pow(identifier_index as u32) % 2 == 1;
82 values.push(value);
83 idens_values.insert(identifier, value);
84 }
85
86 rows.push(TruthTableRow {
87 values,
88 result: expression.evaluate(&idens_values),
89 });
90 }
91
92 Self { variables, rows }
93 }
94}