logical_expression_pest_parser/
truth_table.rs

1use crate::ast::Expression;
2use std::collections::HashMap;
3use std::fmt::{Display, Formatter};
4
5/// Represents a single row in the truth table, containing variable values and the evaluated result.
6#[derive(Debug)]
7pub struct TruthTableRow {
8    /// The specific boolean values for each variable in this row
9    pub values: Vec<bool>,
10    /// The evaluated boolean result of the expression for this row.
11    pub result: bool,
12}
13
14/// Represents the complete truth table for a given expression, with all possible value combinations and their corresponding results.
15#[derive(Debug)]
16pub struct TruthTable {
17    /// A sorted list of unique variables.
18    pub variables: Vec<char>,
19    /// A `Vec` of all `TruthTableRow`s, representing the table's body.
20    pub rows: Vec<TruthTableRow>,
21}
22
23impl Display for TruthTableRow {
24    /// Formats a [TruthTableRow] for printing.
25    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    /// Formats a [TruthTable] for printing.
38    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    /// Creates a `TruthTable`.
60    ///
61    /// It generates a truth table for a given logical expression showing the evaluation result for all possible combinations of its input variables.
62    ///
63    /// # Arguments
64    /// * `expression` - An AST node that represents a parsed logical expression.
65    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}