feat(ex04): boolean evaluation
This commit is contained in:
parent
8031391a61
commit
afb5d7d105
|
@ -0,0 +1,42 @@
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Token {
|
||||
Negation,
|
||||
Conjunction,
|
||||
Disjunction,
|
||||
ExclusiveDisjunction,
|
||||
MaterialCondition,
|
||||
LogicalEquivalence
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Node<T> {
|
||||
Leaf(T),
|
||||
Unary {
|
||||
operator: Token,
|
||||
operand: Box<Node<T>>
|
||||
},
|
||||
Binary {
|
||||
operator: Token,
|
||||
lhs: Box<Node<T>>,
|
||||
rhs: Box<Node<T>>,
|
||||
},
|
||||
}
|
||||
|
||||
pub fn add_unary_node<T>(stack: &mut Vec<Node<T>>, token: Token) {
|
||||
let operand = Box::new(stack.pop().unwrap());
|
||||
stack.push(Node::Unary {
|
||||
operator: token,
|
||||
operand,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn add_binary_node<T>(stack: &mut Vec<Node<T>>, token: Token) {
|
||||
let lhs = Box::new(stack.pop().unwrap());
|
||||
let rhs = Box::new(stack.pop().unwrap());
|
||||
stack.push(Node::Binary {
|
||||
operator: token,
|
||||
lhs,
|
||||
rhs
|
||||
});
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn add_nodes() {
|
||||
let 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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
mod tests;
|
||||
|
||||
use crate::ast::{ Token, Node, add_unary_node, add_binary_node };
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
fn compute(operator: Token, lhs: bool, rhs: bool) -> bool {
|
||||
match operator {
|
||||
Token::Negation => !lhs,
|
||||
Token::Conjunction => lhs & rhs,
|
||||
Token::Disjunction => lhs | rhs,
|
||||
Token::ExclusiveDisjunction => lhs ^ rhs,
|
||||
Token::MaterialCondition => !(lhs && !rhs),
|
||||
Token::LogicalEquivalence => lhs == rhs
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate(tree: Node<bool>) -> bool {
|
||||
match tree {
|
||||
Node::Unary { operator, operand } => compute(operator, evaluate(*operand), false),
|
||||
Node::Binary { operator, lhs, rhs } => compute(operator, evaluate(*lhs), evaluate(*rhs)),
|
||||
Node::Leaf(b) => b,
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_formula(formula: &str) -> bool {
|
||||
let tree = parse_formula(formula);
|
||||
evaluate(tree)
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::boolean_evaluation::eval_formula;
|
||||
|
||||
#[test]
|
||||
fn only_binary() {
|
||||
assert_eq!(eval_formula("10&"), false);
|
||||
assert_eq!(eval_formula("10|"), true);
|
||||
assert_eq!(eval_formula("11>"), true);
|
||||
assert_eq!(eval_formula("10="), false);
|
||||
assert_eq!(eval_formula("1011||="), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn only_unary() {
|
||||
assert_eq!(eval_formula("1!"), false);
|
||||
assert_eq!(eval_formula("0!"), true);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn binary_and_uneray() {
|
||||
assert_eq!(eval_formula("10&!"), true);
|
||||
assert_eq!(eval_formula("11&!"), false);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
mod adder;
|
||||
mod multiplier;
|
||||
mod gray_code;
|
||||
mod boolean_evaluation;
|
||||
mod ast;
|
||||
|
||||
use gray_code::gray_code;
|
||||
|
||||
|
|
Loading…
Reference in New Issue