diff --git a/src/ast.rs b/src/ast.rs index e0efaae..92a5863 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1,5 +1,7 @@ +mod tests; -#[derive(Debug, Clone)] + +#[derive(Debug, Clone, PartialEq)] pub enum Token { Negation, Conjunction, @@ -9,7 +11,7 @@ pub enum Token { LogicalEquivalence } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum Node { Leaf(T), Unary { @@ -32,11 +34,46 @@ pub fn add_unary_node(stack: &mut Vec>, token: Token) { } pub fn add_binary_node(stack: &mut Vec>, token: Token) { - let lhs = Box::new(stack.pop().unwrap()); let rhs = Box::new(stack.pop().unwrap()); + let lhs = Box::new(stack.pop().unwrap()); stack.push(Node::Binary { operator: token, lhs, rhs }); +} + +fn bool_to_char(b: bool) -> char { + match b { + false => '0', + true => '1' + } +} + +fn token_to_char(token: Token) -> char { + match token { + Token::Negation => '!', + Token::Conjunction =>'&', + Token::Disjunction => '|', + Token::ExclusiveDisjunction => '^', + Token::MaterialCondition => '>', + Token::LogicalEquivalence => '=', + } +} + +fn ast_to_formula(ast: Node) -> String { + let mut str = String::from(""); + match ast { + Node::Unary { operator, operand } => { + str.push_str(ast_to_formula(*operand).as_str()); + str.push(token_to_char(operator)); + }, + Node::Binary { operator, lhs, rhs } => { + str.push_str(ast_to_formula(*rhs).as_str()); + str.push_str(ast_to_formula(*lhs).as_str()); + str.push(token_to_char(operator)); + }, + Node::Leaf(b) => str.push(bool_to_char(b)), + }; + str } \ No newline at end of file diff --git a/src/ast/tests.rs b/src/ast/tests.rs index 085d695..25c9509 100644 --- a/src/ast/tests.rs +++ b/src/ast/tests.rs @@ -1,13 +1,31 @@ #[cfg(test)] mod tests { + use crate::ast::{ add_binary_node, ast_to_formula, Node, Token }; + use crate::boolean_evaluation::parse_formula; + #[test] fn add_nodes() { - let stack = vec![Node::Leaf(true), Node::Leaf(false)]; + let mut stack = vec![Node::Leaf(true), Node::Leaf(false)]; let rhs = vec![Node::Binary { operator: Token::Conjunction, lhs: Box::new(Node::Leaf(true)), rhs: Box::new(Node::Leaf(false)) }]; - assert_eq!(add_binary_node(&mut stack, Token::Conjunction), rhs); + add_binary_node(&mut stack, Token::Conjunction); + assert_eq!(stack, rhs); + } + + #[test] + fn reverse_ast() { + let formula = "01&"; + assert_eq!(ast_to_formula(parse_formula(formula)), formula); + let formula = "01&00|&"; + assert_eq!(ast_to_formula(parse_formula(formula)), formula); + let formula = "01&00|&11^&"; + assert_eq!(ast_to_formula(parse_formula(formula)), formula); + let formula = "01&00|&11=^"; + assert_eq!(ast_to_formula(parse_formula(formula)), formula); + let formula = "01&00|&0!="; + assert_eq!(ast_to_formula(parse_formula(formula)), formula); } } \ No newline at end of file diff --git a/src/boolean_evaluation.rs b/src/boolean_evaluation.rs index 18f89e7..4a34b80 100644 --- a/src/boolean_evaluation.rs +++ b/src/boolean_evaluation.rs @@ -2,7 +2,7 @@ mod tests; use crate::ast::{ Token, Node, add_unary_node, add_binary_node }; -fn parse_formula(formula: &str) -> Node { +pub fn parse_formula(formula: &str) -> Node { let mut stack = vec![]; for c in formula.chars() { match c { @@ -39,7 +39,7 @@ fn evaluate(tree: Node) -> bool { } } -fn eval_formula(formula: &str) -> bool { +pub fn eval_formula(formula: &str) -> bool { let tree = parse_formula(formula); evaluate(tree) } \ No newline at end of file diff --git a/src/boolean_evaluation/tests.rs b/src/boolean_evaluation/tests.rs index daa6150..2430f40 100644 --- a/src/boolean_evaluation/tests.rs +++ b/src/boolean_evaluation/tests.rs @@ -15,7 +15,6 @@ mod tests { fn only_unary() { assert_eq!(eval_formula("1!"), false); assert_eq!(eval_formula("0!"), true); - } #[test] @@ -24,7 +23,6 @@ mod tests { assert_eq!(eval_formula("0!!"), false); assert_eq!(eval_formula("0!!!"), true); assert_eq!(eval_formula("1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"), true); - } #[test] diff --git a/src/main.rs b/src/main.rs index 79b9e84..5dc93d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,8 @@ mod truth_table; mod ast; use gray_code::gray_code; +use truth_table::print_truth_table; +use boolean_evaluation::eval_formula; fn main() { println!("Hello, world!"); @@ -18,4 +20,14 @@ fn main() { println!("{}", gray_code(15)); println!("{}", gray_code(7)); println!("{}", gray_code(3)); + print_truth_table("ABC|&"); + //print_truth_table("ABCF&&&"); + // println!("{}", eval_formula("000|&")); + // println!("{}", eval_formula("001|&")); + // println!("{}", eval_formula("010|&")); + // println!("{}", eval_formula("011|&")); + // println!("{}", eval_formula("100|&")); + // println!("{}", eval_formula("101|&")); + // println!("{}", eval_formula("110|&")); + // println!("{}", eval_formula("111|&")); } diff --git a/src/truth_table.rs b/src/truth_table.rs index 3ec29f5..284761b 100644 --- a/src/truth_table.rs +++ b/src/truth_table.rs @@ -71,7 +71,7 @@ fn recursive_fn(formula: &str, mut vec: Vec, format: String) { } } -fn print_truth_table(formula: &str) { +pub fn print_truth_table(formula: &str) { let set: HashSet = get_hashset(formula); let mut vec: Vec = set.iter().cloned().collect(); vec.sort(); @@ -87,6 +87,7 @@ fn print_truth_table(formula: &str) { separator = format!("{separator}---|"); println!("{format}"); println!("{separator}"); - recursive_fn(formula, vec, String::from("|")); + //dbg!(vec.clone()); + recursive_fn(formula, vec.into_iter().rev().collect(), String::from("|")); // call eval formula a lot } \ No newline at end of file diff --git a/src/truth_table/tests.rs b/src/truth_table/tests.rs index e092e43..79fcc21 100644 --- a/src/truth_table/tests.rs +++ b/src/truth_table/tests.rs @@ -23,6 +23,6 @@ mod tests { #[test] fn big() { - print_truth_table("AB&CD&&EF&GH&&&IJ&KL&&MN&OP&&&QR&ST&&UV&WX&&&YZ&&&") + //print_truth_table("AB&CD&&EF&GH&&&IJ&KL&&MN&OP&&&QR&ST&&UV&WX&&&YZ&&&") } }