Skip to content

Commit

Permalink
The truth table is a separate object now
Browse files Browse the repository at this point in the history
  • Loading branch information
jsinger67 committed Nov 8, 2023
1 parent 36444bd commit 505243d
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 30 deletions.
3 changes: 2 additions & 1 deletion src/bin/raa_tt/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ fn main() -> Result<()> {

if args.truth_table {
let table_generator = TableGenerator::new();
table_generator.generate_truth_table(&proposition)?;
let truth_table = table_generator.generate_truth_table(&proposition)?;
println!("{}", truth_table);
}
}
Ok(())
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ pub mod raa_tt_grammar;
mod raa_tt_grammar_trait;
pub mod raa_tt_parser;
pub mod table_generator;
pub mod truth_table;
69 changes: 40 additions & 29 deletions src/table_generator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cell::RefCell, collections::BTreeMap, fmt::Write};
use std::{cell::RefCell, collections::BTreeMap};

use crate::{
bi_implication::BiImplication,
Expand All @@ -8,6 +8,7 @@ use crate::{
implication::Implication,
negation::Negation,
proposition::Proposition,
truth_table::TruthTable,
};

impl Proposition {
Expand Down Expand Up @@ -38,6 +39,7 @@ impl Proposition {

#[derive(Debug, Default)]
pub struct TableGenerator {
// Variable set paired with values that change in every line
vars: RefCell<BTreeMap<String, bool>>,
}

Expand All @@ -46,7 +48,7 @@ impl TableGenerator {
Self::default()
}

pub fn generate_truth_table(&self, proposition: &Proposition) -> Result<()> {
pub fn generate_truth_table(&self, proposition: &Proposition) -> Result<TruthTable> {
let vars = proposition.get_variables();
*self.vars.borrow_mut() = vars.iter().fold(BTreeMap::new(), |mut acc, v| {
acc.insert(v.clone(), false);
Expand All @@ -55,44 +57,53 @@ impl TableGenerator {
if self.number_of_vars() > 16 {
return Err(RaaError::TooManyVariables);
}
let var_part = self.generate_table_header()?;
let prp_part = proposition.to_string();
println!("{var_part} {prp_part}");
println!("{}", "-".repeat(var_part.len() + prp_part.len()));
for v in 0..2usize.pow(self.number_of_vars()) {
self.generate_table_line(v, proposition)?;
}
Ok(())
let header = self.generate_table_header(proposition);
let line_count = 2usize.pow(self.number_of_vars());
let lines = Vec::with_capacity(line_count);
let lines = (0..line_count).try_fold(lines, |mut lines, v| {
self.generate_table_line(v, proposition).map(|line| {
lines.push(line);
lines
})
})?;
Ok(TruthTable { header, lines })
}

fn generate_table_header(&self) -> Result<String> {
let mut line = String::new();
self.vars.borrow().keys().try_for_each(|var| {
write!(line, "{var} | ").map_err(|e| RaaError::FormatError { source: e })
})?;
Ok(line)
fn generate_table_header(&self, proposition: &Proposition) -> Vec<String> {
let mut header = self.vars.borrow().keys().fold(
Vec::with_capacity(self.vars.borrow().len() + 1),
|mut acc, var| {
acc.push(var.clone());
acc
},
);
header.push(proposition.to_string());
header
}

#[inline]
fn number_of_vars(&self) -> u32 {
self.vars.borrow().len() as u32
}

fn generate_table_line(&self, v: usize, proposition: &Proposition) -> Result<()> {
fn generate_table_line(&self, v: usize, proposition: &Proposition) -> Result<Vec<bool>> {
let n = self.number_of_vars();
let mut bit = if n == 0 { 0 } else { 1 << (n - 1) };
self.vars.borrow_mut().iter_mut().for_each(|(var, val)| {
// Extract the variable value from the bits of number v which is increased for each line
let b = v & bit != 0;
*val = b;
let t = if b { "T" } else { "F" };
print!("{t:w$} | ", w = var.len());
bit >>= 1;
});
let mut line =
self.vars
.borrow_mut()
.iter_mut()
.fold(Vec::new(), |mut acc, (_var, val)| {
// Extract the variable value from the bits of number v which is increased for
// each line outside.
let b = v & bit != 0;
*val = b;
acc.push(b);
bit >>= 1;
acc
});
let b = proposition.calculate_value(&self.vars.borrow())?;
let t = if b { "T" } else { "F" };
print!(" {t}");
println!();
Ok(())
line.push(b);
Ok(line)
}
}
29 changes: 29 additions & 0 deletions src/truth_table.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::fmt::{Debug, Display, Error, Formatter};

#[derive(Debug)]
pub struct TruthTable {
pub header: Vec<String>,
pub lines: Vec<Vec<bool>>,
}

impl Display for TruthTable {
fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> {
self.header
.iter()
.try_for_each(|var| write!(f, "{var} | "))?;
writeln!(f)?;
self.header
.iter()
.try_for_each(|var| write!(f, "{}", "-".repeat(var.len() + 3)))?;
writeln!(f)?;
self.lines.iter().try_for_each(|line| {
debug_assert_eq!(line.len(), self.header.len());
self.header.iter().enumerate().try_for_each(|(i, var)| {
let b = line[i];
let t = if b { "T" } else { "F" };
write!(f, "{t:w$} | ", w = var.len())
})?;
writeln!(f)
})
}
}

0 comments on commit 505243d

Please sign in to comment.