feat(ex05): cancel double negation
This commit is contained in:
parent
a13dfeaeeb
commit
b5e48c41c4
52
src/ast.rs
52
src/ast.rs
|
@ -1,7 +1,7 @@
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
Negation,
|
Negation,
|
||||||
Conjunction,
|
Conjunction,
|
||||||
|
@ -25,6 +25,28 @@ pub enum Node<T> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Node<T>
|
||||||
|
where T: Clone {
|
||||||
|
pub fn simplify(&mut self) {
|
||||||
|
match self {
|
||||||
|
Node::Unary { operator, operand } if *operator == Token::Negation => {
|
||||||
|
if let Node::Unary { operator: inner_op, operand: inner_operand } = &**operand {
|
||||||
|
if *inner_op == Token::Negation {
|
||||||
|
*self = *inner_operand.clone(); // Replace unary node with its operand
|
||||||
|
self.simplify(); // Continue simplification recursively
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Node::Binary { lhs, rhs, .. } => {
|
||||||
|
lhs.simplify();
|
||||||
|
rhs.simplify();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Node<bool> {
|
impl Node<bool> {
|
||||||
pub fn parse_formula(formula: &str) -> Node<bool> {
|
pub fn parse_formula(formula: &str) -> Node<bool> {
|
||||||
let mut stack = vec![];
|
let mut stack = vec![];
|
||||||
|
@ -44,19 +66,19 @@ impl Node<bool> {
|
||||||
stack.pop().unwrap()
|
stack.pop().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ast_to_formula(ast: Node<bool>) -> String {
|
pub fn ast_to_formula(ast: &Node<bool>) -> String {
|
||||||
let mut str = String::from("");
|
let mut str = String::from("");
|
||||||
match ast {
|
match ast {
|
||||||
Node::Unary { operator, operand } => {
|
Node::Unary { operator, operand } => {
|
||||||
str.push_str(Self::ast_to_formula(*operand).as_str());
|
str.push_str(Self::ast_to_formula(operand).as_str());
|
||||||
str.push(token_to_char(operator));
|
str.push(token_to_char(*operator));
|
||||||
},
|
},
|
||||||
Node::Binary { operator, lhs, rhs } => {
|
Node::Binary { operator, lhs, rhs } => {
|
||||||
str.push_str(Self::ast_to_formula(*lhs).as_str());
|
str.push_str(Self::ast_to_formula(lhs).as_str());
|
||||||
str.push_str(Self::ast_to_formula(*rhs).as_str());
|
str.push_str(Self::ast_to_formula(rhs).as_str());
|
||||||
str.push(token_to_char(operator));
|
str.push(token_to_char(*operator));
|
||||||
},
|
},
|
||||||
Node::Leaf(b) => str.push(bool_to_char(b)),
|
Node::Leaf(b) => str.push(bool_to_char(*b)),
|
||||||
};
|
};
|
||||||
str
|
str
|
||||||
}
|
}
|
||||||
|
@ -80,19 +102,19 @@ impl Node<char> {
|
||||||
stack.pop().unwrap()
|
stack.pop().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ast_to_formula(ast: Node<char>) -> String {
|
pub fn ast_to_formula(ast: &Node<char>) -> String {
|
||||||
let mut str = String::from("");
|
let mut str = String::from("");
|
||||||
match ast {
|
match ast {
|
||||||
Node::Unary { operator, operand } => {
|
Node::Unary { operator, operand } => {
|
||||||
str.push_str(Self::ast_to_formula(*operand).as_str());
|
str.push_str(Self::ast_to_formula(operand).as_str());
|
||||||
str.push(token_to_char(operator));
|
str.push(token_to_char(*operator));
|
||||||
},
|
},
|
||||||
Node::Binary { operator, lhs, rhs } => {
|
Node::Binary { operator, lhs, rhs } => {
|
||||||
str.push_str(Self::ast_to_formula(*lhs).as_str());
|
str.push_str(Self::ast_to_formula(lhs).as_str());
|
||||||
str.push_str(Self::ast_to_formula(*rhs).as_str());
|
str.push_str(Self::ast_to_formula(rhs).as_str());
|
||||||
str.push(token_to_char(operator));
|
str.push(token_to_char(*operator));
|
||||||
},
|
},
|
||||||
Node::Leaf(c) => str.push(c),
|
Node::Leaf(c) => str.push(*c),
|
||||||
};
|
};
|
||||||
str
|
str
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,28 +17,28 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn ast_to_formula_bool() {
|
fn ast_to_formula_bool() {
|
||||||
let formula = "01&";
|
let formula = "01&";
|
||||||
assert_eq!(Node::<bool>::ast_to_formula(Node::<bool>::parse_formula(formula)), formula);
|
assert_eq!(Node::<bool>::ast_to_formula(&Node::<bool>::parse_formula(formula)), formula);
|
||||||
let formula = "01&00|&";
|
let formula = "01&00|&";
|
||||||
assert_eq!(Node::<bool>::ast_to_formula(Node::<bool>::parse_formula(formula)), formula);
|
assert_eq!(Node::<bool>::ast_to_formula(&Node::<bool>::parse_formula(formula)), formula);
|
||||||
let formula = "01&00|&11^&";
|
let formula = "01&00|&11^&";
|
||||||
assert_eq!(Node::<bool>::ast_to_formula(Node::<bool>::parse_formula(formula)), formula);
|
assert_eq!(Node::<bool>::ast_to_formula(&Node::<bool>::parse_formula(formula)), formula);
|
||||||
let formula = "01&00|&11=^";
|
let formula = "01&00|&11=^";
|
||||||
assert_eq!(Node::<bool>::ast_to_formula(Node::<bool>::parse_formula(formula)), formula);
|
assert_eq!(Node::<bool>::ast_to_formula(&Node::<bool>::parse_formula(formula)), formula);
|
||||||
let formula = "01&00|&0!=";
|
let formula = "01&00|&0!=";
|
||||||
assert_eq!(Node::<bool>::ast_to_formula(Node::<bool>::parse_formula(formula)), formula);
|
assert_eq!(Node::<bool>::ast_to_formula(&Node::<bool>::parse_formula(formula)), formula);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ast_to_formula_char() {
|
fn ast_to_formula_char() {
|
||||||
let formula = "AB&";
|
let formula = "AB&";
|
||||||
assert_eq!(Node::<char>::ast_to_formula(Node::<char>::parse_formula(formula)), formula);
|
assert_eq!(Node::<char>::ast_to_formula(&Node::<char>::parse_formula(formula)), formula);
|
||||||
let formula = "AB&CD|&";
|
let formula = "AB&CD|&";
|
||||||
assert_eq!(Node::<char>::ast_to_formula(Node::<char>::parse_formula(formula)), formula);
|
assert_eq!(Node::<char>::ast_to_formula(&Node::<char>::parse_formula(formula)), formula);
|
||||||
let formula = "AB&AC|&DE^&";
|
let formula = "AB&AC|&DE^&";
|
||||||
assert_eq!(Node::<char>::ast_to_formula(Node::<char>::parse_formula(formula)), formula);
|
assert_eq!(Node::<char>::ast_to_formula(&Node::<char>::parse_formula(formula)), formula);
|
||||||
let formula = "AB&CD|&EF=^";
|
let formula = "AB&CD|&EF=^";
|
||||||
assert_eq!(Node::<char>::ast_to_formula(Node::<char>::parse_formula(formula)), formula);
|
assert_eq!(Node::<char>::ast_to_formula(&Node::<char>::parse_formula(formula)), formula);
|
||||||
let formula = "AB&CD|&E!=";
|
let formula = "AB&CD|&E!=";
|
||||||
assert_eq!(Node::<char>::ast_to_formula(Node::<char>::parse_formula(formula)), formula);
|
assert_eq!(Node::<char>::ast_to_formula(&Node::<char>::parse_formula(formula)), formula);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,25 @@ mod tests;
|
||||||
|
|
||||||
use crate::ast::Node;
|
use crate::ast::Node;
|
||||||
|
|
||||||
|
// fn cancel_double_negation(ast: &mut Node<char>, parent: Option<&mut Node<char>>) -> Node<char> {
|
||||||
|
// match ast {
|
||||||
|
// Node::Unary { operator: _, operand } => {
|
||||||
|
// if let Some(node) = parent {
|
||||||
|
|
||||||
|
// } else {
|
||||||
|
// *ast = cancel_double_negation(&mut *operand, Some(ast));
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// Node::Binary { operator: _, lhs, rhs } => {
|
||||||
|
// *ast = cancel_double_negation(&mut *lhs, None);
|
||||||
|
// *ast = cancel_double_negation(&mut *rhs, None);
|
||||||
|
// },
|
||||||
|
// Node::Leaf(c) => (),
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ast
|
||||||
|
// }
|
||||||
|
|
||||||
// fn cancel_double_negation(ast: Node<char>) {
|
// fn cancel_double_negation(ast: Node<char>) {
|
||||||
// let mut new_ast = ast.clone();
|
// let mut new_ast = ast.clone();
|
||||||
|
|
||||||
|
@ -24,7 +43,35 @@ use crate::ast::Node;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
fn negation_normal_form(formula: &str) -> String {
|
fn negation_normal_form(formula: &str) -> String {
|
||||||
let ast = Node::<char>::parse_formula(formula);
|
let mut ast = Node::<char>::parse_formula(formula);
|
||||||
|
// let mut tmp = Node::<char>::parse_formula((formula.to_string() + "!").as_str());
|
||||||
|
// let mut clone = ast.clone();
|
||||||
|
|
||||||
Node::<char>::ast_to_formula(ast)
|
// while Node::<char>::ast_to_formula(&clone) != Node::<char>::ast_to_formula(&tmp) {
|
||||||
|
// let copy = ast.clone();
|
||||||
|
// clone = ast.clone();
|
||||||
|
|
||||||
|
// dbg!(&ast);
|
||||||
|
|
||||||
|
// tmp = match copy {
|
||||||
|
// Node::Unary { operator: _, operand } => {
|
||||||
|
// match *operand {
|
||||||
|
// Node::Unary { operator: _, operand } => {
|
||||||
|
// println!("salut");
|
||||||
|
// dbg!(&*operand);
|
||||||
|
// *operand
|
||||||
|
// }
|
||||||
|
// Node::Binary { operator: _, lhs: _, rhs: _ } => ast,
|
||||||
|
// Node::Leaf(_) => ast,
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// Node::Binary { operator: _, lhs: _, rhs: _ } => ast,
|
||||||
|
// Node::Leaf(_) => ast,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// ast = tmp.clone();
|
||||||
|
// }
|
||||||
|
ast.simplify();
|
||||||
|
Node::<char>::ast_to_formula(&ast)
|
||||||
}
|
}
|
|
@ -3,12 +3,19 @@ mod tests {
|
||||||
use crate::negation_normal_form::negation_normal_form;
|
use crate::negation_normal_form::negation_normal_form;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn double_neg() {
|
fn double_neg_simple() {
|
||||||
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("B!!!!"), "B");
|
||||||
assert_eq!(negation_normal_form("A!!!"), "A!");
|
assert_eq!(negation_normal_form("C!!!"), "C!");
|
||||||
assert_eq!(negation_normal_form("A!!!!!!!!!!!!!!!!"), "A");
|
assert_eq!(negation_normal_form("D!!!!!!!!!!!!!!!!"), "D");
|
||||||
assert_eq!(negation_normal_form("A!!!!!!!!!!!!!!!"), "A!");
|
assert_eq!(negation_normal_form("E!!!!!!!!!!!!!!!"), "E!");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn double_neg() {
|
||||||
|
assert_eq!(negation_normal_form("A!!B&"), "AB&");
|
||||||
|
assert_eq!(negation_normal_form("A!!B!!&"), "AB&");
|
||||||
|
assert_eq!(negation_normal_form("A!!B!&"), "AB!&");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue