refacto: use generic types
This commit is contained in:
		
							parent
							
								
									2300d91fad
								
							
						
					
					
						commit
						a13dfeaeeb
					
				
							
								
								
									
										89
									
								
								src/ast.rs
								
								
								
								
							
							
						
						
									
										89
									
								
								src/ast.rs
								
								
								
								
							|  | @ -25,6 +25,79 @@ pub enum Node<T> { | |||
|     }, | ||||
| } | ||||
| 
 | ||||
| impl Node<bool> { | ||||
|     pub fn parse_formula(formula: &str) -> Node<bool> { | ||||
|         let mut stack = vec![]; | ||||
|         for c in formula.chars() { | ||||
|             match c { | ||||
|                 '0' => stack.push(Node::Leaf(false)), | ||||
|                 '1' => stack.push(Node::Leaf(true)), | ||||
|                 '!' => add_unary_node(&mut stack, Token::Negation), | ||||
|                 '&' => add_binary_node(&mut stack, Token::Conjunction), | ||||
|                 '|' => add_binary_node(&mut stack, Token::Disjunction), | ||||
|                 '^' => add_binary_node(&mut stack, Token::ExclusiveDisjunction), | ||||
|                 '>' => add_binary_node(&mut stack, Token::MaterialCondition), | ||||
|                 '=' => add_binary_node(&mut stack, Token::LogicalEquivalence), | ||||
|                 _ => panic!("Error: {} is not a valid character", c) | ||||
|             } | ||||
|         } | ||||
|         stack.pop().unwrap() | ||||
|     } | ||||
| 
 | ||||
|     pub fn ast_to_formula(ast: Node<bool>) -> String { | ||||
|         let mut str = String::from(""); | ||||
|         match ast { | ||||
|             Node::Unary { operator, operand } => { | ||||
|                 str.push_str(Self::ast_to_formula(*operand).as_str()); | ||||
|                 str.push(token_to_char(operator)); | ||||
|             }, | ||||
|             Node::Binary { operator, lhs, rhs } => { | ||||
|                 str.push_str(Self::ast_to_formula(*lhs).as_str()); | ||||
|                 str.push_str(Self::ast_to_formula(*rhs).as_str()); | ||||
|                 str.push(token_to_char(operator)); | ||||
|             }, | ||||
|             Node::Leaf(b) => str.push(bool_to_char(b)), | ||||
|         }; | ||||
|         str | ||||
|     } | ||||
| }   
 | ||||
| 
 | ||||
| impl Node<char> { | ||||
|     pub fn parse_formula(formula: &str) -> Node<char> { | ||||
|         let mut stack = vec![]; | ||||
|         for c in formula.chars() { | ||||
|             match c { | ||||
|                 'A'..='Z' => stack.push(Node::Leaf(c)), | ||||
|                 '!' => add_unary_node(&mut stack, Token::Negation), | ||||
|                 '&' => add_binary_node(&mut stack, Token::Conjunction), | ||||
|                 '|' => add_binary_node(&mut stack, Token::Disjunction), | ||||
|                 '^' => add_binary_node(&mut stack, Token::ExclusiveDisjunction), | ||||
|                 '>' => add_binary_node(&mut stack, Token::MaterialCondition), | ||||
|                 '=' => add_binary_node(&mut stack, Token::LogicalEquivalence), | ||||
|                 _ => panic!("Error: {} is not a valid character", c) | ||||
|             } | ||||
|         } | ||||
|         stack.pop().unwrap() | ||||
|     } | ||||
| 
 | ||||
|     pub fn ast_to_formula(ast: Node<char>) -> String { | ||||
|         let mut str = String::from(""); | ||||
|         match ast { | ||||
|             Node::Unary { operator, operand } => { | ||||
|                 str.push_str(Self::ast_to_formula(*operand).as_str()); | ||||
|                 str.push(token_to_char(operator)); | ||||
|             }, | ||||
|             Node::Binary { operator, lhs, rhs } => { | ||||
|                 str.push_str(Self::ast_to_formula(*lhs).as_str()); | ||||
|                 str.push_str(Self::ast_to_formula(*rhs).as_str()); | ||||
|                 str.push(token_to_char(operator)); | ||||
|             }, | ||||
|             Node::Leaf(c) => str.push(c), | ||||
|         }; | ||||
|         str | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn add_unary_node<T>(stack: &mut Vec<Node<T>>, token: Token) { | ||||
|     let operand = Box::new(stack.pop().unwrap()); | ||||
|     stack.push(Node::Unary { | ||||
|  | @ -61,19 +134,3 @@ fn token_to_char(token: Token) -> char { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| fn ast_to_formula(ast: Node<bool>) -> 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 | ||||
| } | ||||
|  | @ -1,7 +1,6 @@ | |||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::ast::{ add_binary_node, ast_to_formula, Node, Token }; | ||||
|     use crate::boolean_evaluation::parse_formula; | ||||
|     use crate::ast::{ add_binary_node, Node, Token }; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn add_nodes() { | ||||
|  | @ -16,16 +15,30 @@ mod tests { | |||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn reverse_ast() { | ||||
|     fn ast_to_formula_bool() { | ||||
|         let formula = "01&"; | ||||
|         assert_eq!(ast_to_formula(parse_formula(formula)), formula); | ||||
|         assert_eq!(Node::<bool>::ast_to_formula(Node::<bool>::parse_formula(formula)), formula); | ||||
|         let formula = "01&00|&"; | ||||
|         assert_eq!(ast_to_formula(parse_formula(formula)), formula); | ||||
|         assert_eq!(Node::<bool>::ast_to_formula(Node::<bool>::parse_formula(formula)), formula); | ||||
|         let formula = "01&00|&11^&"; | ||||
|         assert_eq!(ast_to_formula(parse_formula(formula)), formula); | ||||
|         assert_eq!(Node::<bool>::ast_to_formula(Node::<bool>::parse_formula(formula)), formula); | ||||
|         let formula = "01&00|&11=^"; | ||||
|         assert_eq!(ast_to_formula(parse_formula(formula)), formula); | ||||
|         assert_eq!(Node::<bool>::ast_to_formula(Node::<bool>::parse_formula(formula)), formula); | ||||
|         let formula = "01&00|&0!="; | ||||
|         assert_eq!(ast_to_formula(parse_formula(formula)), formula); | ||||
|         assert_eq!(Node::<bool>::ast_to_formula(Node::<bool>::parse_formula(formula)), formula); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn ast_to_formula_char() { | ||||
|         let formula = "AB&"; | ||||
|         assert_eq!(Node::<char>::ast_to_formula(Node::<char>::parse_formula(formula)), formula); | ||||
|         let formula = "AB&CD|&"; | ||||
|         assert_eq!(Node::<char>::ast_to_formula(Node::<char>::parse_formula(formula)), formula); | ||||
|         let formula = "AB&AC|&DE^&"; | ||||
|         assert_eq!(Node::<char>::ast_to_formula(Node::<char>::parse_formula(formula)), formula); | ||||
|         let formula = "AB&CD|&EF=^"; | ||||
|         assert_eq!(Node::<char>::ast_to_formula(Node::<char>::parse_formula(formula)), formula); | ||||
|         let formula = "AB&CD|&E!="; | ||||
|         assert_eq!(Node::<char>::ast_to_formula(Node::<char>::parse_formula(formula)), formula); | ||||
|     } | ||||
| } | ||||
|  | @ -1,24 +1,6 @@ | |||
| mod tests; | ||||
| 
 | ||||
| use crate::ast::{ Token, Node, add_unary_node, add_binary_node }; | ||||
| 
 | ||||
| pub fn parse_formula(formula: &str) -> Node<bool> { | ||||
|     let mut stack = vec![]; | ||||
|     for c in formula.chars() { | ||||
|         match c { | ||||
|             '0' => stack.push(Node::Leaf(false)), | ||||
|             '1' => stack.push(Node::Leaf(true)), | ||||
|             '!' => add_unary_node(&mut stack, Token::Negation), | ||||
|             '&' => add_binary_node(&mut stack, Token::Conjunction), | ||||
|             '|' => add_binary_node(&mut stack, Token::Disjunction), | ||||
|             '^' => add_binary_node(&mut stack, Token::ExclusiveDisjunction), | ||||
|             '>' => add_binary_node(&mut stack, Token::MaterialCondition), | ||||
|             '=' => add_binary_node(&mut stack, Token::LogicalEquivalence), | ||||
|             _ => panic!("Error: {} is not a valid character", c) | ||||
|         } | ||||
|     } | ||||
|     stack.pop().unwrap() | ||||
| } | ||||
| use crate::ast::{ Token, Node }; | ||||
| 
 | ||||
| fn compute(operator: Token, lhs: bool, rhs: bool) -> bool { | ||||
|     match operator { | ||||
|  | @ -40,6 +22,6 @@ fn evaluate(tree: Node<bool>) -> bool { | |||
| } | ||||
| 
 | ||||
| pub fn eval_formula(formula: &str) -> bool { | ||||
|     let tree = parse_formula(formula); | ||||
|     let tree = Node::<bool>::parse_formula(formula); | ||||
|     evaluate(tree) | ||||
| } | ||||
							
								
								
									
										11
									
								
								src/main.rs
								
								
								
								
							
							
						
						
									
										11
									
								
								src/main.rs
								
								
								
								
							|  | @ -4,10 +4,10 @@ mod gray_code; | |||
| mod boolean_evaluation; | ||||
| mod truth_table; | ||||
| mod ast; | ||||
| mod negation_normal_form; | ||||
| 
 | ||||
| use gray_code::gray_code; | ||||
| use truth_table::print_truth_table; | ||||
| use boolean_evaluation::eval_formula; | ||||
| 
 | ||||
| fn main() { | ||||
|     println!("Hello, world!"); | ||||
|  | @ -21,13 +21,4 @@ fn main() { | |||
|     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|&"));
 | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,30 @@ | |||
| mod tests; | ||||
| 
 | ||||
| use crate::ast::Node; | ||||
| 
 | ||||
| // fn cancel_double_negation(ast: Node<char>) {
 | ||||
| //     let mut new_ast = ast.clone();
 | ||||
| 
 | ||||
| //     fn recursion(ast: &mut Node<char>, node_count: usize) {
 | ||||
| //         match ast {
 | ||||
| //             Node::Unary { operator: _, operand } => {
 | ||||
| //                 recursion(&mut *operand, node_count + 1);
 | ||||
| //             },
 | ||||
| //             Node::Binary { operator: _, lhs, rhs } => {
 | ||||
| //                 recursion(&mut *lhs, node_count + 1);
 | ||||
| //                 recursion(&mut *rhs, node_count + 1);
 | ||||
| //             },
 | ||||
| //             Node::Leaf(c) => (),
 | ||||
| //         }
 | ||||
| //     }
 | ||||
| 
 | ||||
| //     recursion(&mut new_ast, 0);
 | ||||
| 
 | ||||
| //     new_ast
 | ||||
| // }
 | ||||
| 
 | ||||
| fn negation_normal_form(formula: &str) -> String { | ||||
|     let ast = Node::<char>::parse_formula(formula); | ||||
| 
 | ||||
|     Node::<char>::ast_to_formula(ast) | ||||
| } | ||||
|  | @ -0,0 +1,23 @@ | |||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::negation_normal_form::negation_normal_form; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn double_neg() { | ||||
|         assert_eq!(negation_normal_form("A!!"), "A"); | ||||
|         assert_eq!(negation_normal_form("A!!!!"), "A"); | ||||
|         assert_eq!(negation_normal_form("A!!!"), "A!"); | ||||
|         assert_eq!(negation_normal_form("A!!!!!!!!!!!!!!!!"), "A"); | ||||
|         assert_eq!(negation_normal_form("A!!!!!!!!!!!!!!!"), "A!"); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn neg_and() { | ||||
|         assert_eq!(negation_normal_form("AB&!"), "A!B!|"); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn neg_or() { | ||||
|         assert_eq!(negation_normal_form("AB|!"), "A!B!&"); | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue