Fixed parenthesis when not needed. Removed some unused functions
This commit is contained in:
parent
9226060397
commit
78368772eb
@ -4,7 +4,6 @@ use std::rc::Rc;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::expressions::iterator::ExpressionIterator;
|
||||
use crate::expressions::operator::BinaryOperator;
|
||||
use crate::parsing::expression_parser::parse_expression;
|
||||
|
||||
@ -40,19 +39,6 @@ impl Expression {
|
||||
Expression::Atomic(value) => HashSet::from([value.clone()])
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> ExpressionIterator {
|
||||
ExpressionIterator::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for Expression {
|
||||
type Item = Rc<Expression>;
|
||||
type IntoIter = ExpressionIterator;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
ExpressionIterator::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl OppositeEq for Expression {
|
||||
@ -83,20 +69,27 @@ impl TryFrom<String> for Expression {
|
||||
|
||||
impl Display for Expression {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Expression::Not(expr) if expr.is_atomic() => write!(f, "¬{expr}"),
|
||||
Expression::Not(expr) => write!(f, "¬({expr})"),
|
||||
Expression::Binary { left, operator: BinaryOperator::And, right } => {
|
||||
write!(f, "{left} ⋀ {right}")
|
||||
return write!(f, "{}", fmt_helper(self, None));
|
||||
|
||||
fn fmt_helper(expression: &Expression, parent: Option<&Expression>) -> String {
|
||||
match expression {
|
||||
Expression::Not(expr) if expr.is_atomic() => format!("¬{}", fmt_helper(expr, Some(expression))),
|
||||
Expression::Not(expr) => format!("¬({})", fmt_helper(expr, Some(expression))),
|
||||
Expression::Binary { left, operator: BinaryOperator::And, right } => {
|
||||
format!("{} ⋀ {}", fmt_helper(left, Some(expression)), fmt_helper(right, Some(expression)))
|
||||
}
|
||||
Expression::Binary { left, operator: BinaryOperator::Or, right } => {
|
||||
if parent.is_none() || matches!(parent, Some(Expression::Binary { operator: BinaryOperator::Or, .. })) {
|
||||
format!("{} ⋁ {}", fmt_helper(left, Some(expression)), fmt_helper(right, Some(expression)))
|
||||
} else {
|
||||
format!("({} ⋁ {})", fmt_helper(left, Some(expression)), fmt_helper(right, Some(expression)))
|
||||
}
|
||||
}
|
||||
Expression::Binary { left, operator: BinaryOperator::Implication, right } => {
|
||||
format!("{} ➔ {}", fmt_helper(left, Some(expression)), fmt_helper(right, Some(expression)))
|
||||
}
|
||||
Expression::Atomic(value) => value.clone(),
|
||||
}
|
||||
// TODO do not use parentheses on root level or if several operators are on the same level
|
||||
Expression::Binary { left, operator: BinaryOperator::Or, right } => {
|
||||
write!(f, "({left} ⋁ {right})")
|
||||
}
|
||||
Expression::Binary { left, operator: BinaryOperator::Implication, right } => {
|
||||
write!(f, "{left} ➔ {right}")
|
||||
}
|
||||
Expression::Atomic(value) => write!(f, "{value}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,9 +109,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_expression_a_or_b_and_c_display() {
|
||||
// TODO
|
||||
let expression = or(
|
||||
atomic("a"),
|
||||
and(
|
||||
@ -128,6 +119,57 @@ mod tests {
|
||||
assert_eq!(expression.to_string(), "a ⋁ b ⋀ c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expression_a_or_b() {
|
||||
let expression = or(
|
||||
atomic("a"),
|
||||
atomic("b"),
|
||||
);
|
||||
assert_eq!(expression.to_string(), "a ⋁ b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expression_double_or() {
|
||||
let expression = or(
|
||||
atomic("a"),
|
||||
or(
|
||||
atomic("b"),
|
||||
atomic("c"),
|
||||
),
|
||||
);
|
||||
assert_eq!(expression.to_string(), "a ⋁ b ⋁ c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expression_triple_or() {
|
||||
let expression = or(
|
||||
atomic("a"),
|
||||
or(
|
||||
atomic("b"),
|
||||
or(
|
||||
atomic("c"),
|
||||
atomic("d"),
|
||||
),
|
||||
),
|
||||
);
|
||||
assert_eq!(expression.to_string(), "a ⋁ b ⋁ c ⋁ d");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expression_nested_parenthesized_or() {
|
||||
let expression = or(
|
||||
atomic("a"),
|
||||
and(
|
||||
atomic("b"),
|
||||
or(
|
||||
atomic("b"),
|
||||
atomic("c"),
|
||||
),
|
||||
),
|
||||
);
|
||||
assert_eq!(expression.to_string(), "a ⋁ b ⋀ (b ⋁ c)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expression_c_and_a_or_b_display() {
|
||||
let expression = and(
|
||||
|
@ -1,50 +0,0 @@
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
use crate::expressions::expression::Expression;
|
||||
|
||||
pub struct ExpressionIterator {
|
||||
stack: Vec<Rc<Expression>>,
|
||||
}
|
||||
|
||||
impl ExpressionIterator {
|
||||
pub fn new(expression: Expression) -> Self {
|
||||
let stack = vec![expression.into()];
|
||||
Self { stack }
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for ExpressionIterator {
|
||||
type Item = Rc<Expression>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let expression = self.stack.pop()?;
|
||||
match expression.deref() {
|
||||
Expression::Atomic(_) => Some(expression),
|
||||
Expression::Not(inner) => {
|
||||
self.stack.push(inner.clone());
|
||||
Some(expression)
|
||||
}
|
||||
Expression::Binary { left, right, .. } => {
|
||||
self.stack.push(right.clone());
|
||||
self.stack.push(left.clone());
|
||||
Some(expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::expressions::helpers::{and, atomic, not};
|
||||
|
||||
#[test]
|
||||
fn test_expression_iterator() {
|
||||
let expression = not(and(atomic("A"), atomic("B")));
|
||||
let mut iterator = expression.iter();
|
||||
assert_eq!(iterator.next().unwrap(), expression.into());
|
||||
assert_eq!(iterator.next().unwrap(), and(atomic("A"), atomic("B")).into());
|
||||
assert_eq!(iterator.next().unwrap(), atomic("A").into());
|
||||
assert_eq!(iterator.next().unwrap(), atomic("B").into());
|
||||
assert_eq!(iterator.next(), None);
|
||||
}
|
||||
}
|
@ -2,5 +2,4 @@ pub mod expression;
|
||||
pub mod operator;
|
||||
pub mod helpers;
|
||||
pub mod simplify;
|
||||
pub mod truth_table;
|
||||
mod iterator;
|
||||
pub mod truth_table;
|
@ -271,7 +271,7 @@ mod tests {
|
||||
assert_eq!(operations.len(), 1);
|
||||
assert_eq!(operations[0].law, Law::EliminationOfImplication);
|
||||
assert_eq!(operations[0].before, "a ➔ b");
|
||||
assert_eq!(operations[0].after, "(¬a ⋁ b)");
|
||||
assert_eq!(operations[0].after, "¬a ⋁ b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -282,10 +282,10 @@ mod tests {
|
||||
assert_eq!(operations.len(), 2);
|
||||
assert_eq!(operations[0].law, Law::EliminationOfImplication);
|
||||
assert_eq!(operations[0].before, "b ➔ c");
|
||||
assert_eq!(operations[0].after, "(¬b ⋁ c)");
|
||||
assert_eq!(operations[0].after, "¬b ⋁ c");
|
||||
assert_eq!(operations[1].law, Law::EliminationOfImplication);
|
||||
assert_eq!(operations[1].before, "a ➔ b ➔ c");
|
||||
assert_eq!(operations[1].after, "(¬a ⋁ (¬b ⋁ c))");
|
||||
assert_eq!(operations[1].after, "¬a ⋁ ¬b ⋁ c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -362,7 +362,7 @@ mod tests {
|
||||
assert_eq!(operations.len(), 1);
|
||||
assert_eq!(operations[0].law, Law::DeMorgansLaws);
|
||||
assert_eq!(operations[0].before, "¬(a ⋀ b)");
|
||||
assert_eq!(operations[0].after, "(¬a ⋁ ¬b)");
|
||||
assert_eq!(operations[0].after, "¬a ⋁ ¬b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -188,7 +188,7 @@ mod tests {
|
||||
let truth_table = TruthTable::new(&expression, Default::default());
|
||||
let atomics = 3;
|
||||
|
||||
assert_eq!(truth_table.header, vec!["A", "C", "(A ⋁ C)", "B", "(B ⋁ C)", "(A ⋁ C) ⋀ (B ⋁ C)"]);
|
||||
assert_eq!(truth_table.header, vec!["A", "C", "A ⋁ C", "B", "B ⋁ C", "(A ⋁ C) ⋀ (B ⋁ C)"]);
|
||||
assert_eq!(truth_table.truth_matrix.len(), 2usize.pow(atomics as u32));
|
||||
assert_eq!(truth_table.truth_matrix[0].len(), 6);
|
||||
assert_eq!(truth_table.truth_matrix[0], vec![true, true, true, true, true, true]);
|
||||
@ -361,7 +361,7 @@ mod tests {
|
||||
fn test_resolve_expression_or_1_true_1_false() {
|
||||
let expression = or(atomic("A"), atomic("B"));
|
||||
let booleans = map!["A".into() => true, "B".into() => false];
|
||||
let header = vec!["A".into(), "B".into(), "(A ⋁ B)".into()];
|
||||
let header = vec!["A".into(), "B".into(), "A ⋁ B".into()];
|
||||
let values = TruthTable::resolve_expression(&expression, &booleans, &header);
|
||||
assert_eq!(values, vec![true, false, true]);
|
||||
}
|
||||
@ -423,7 +423,7 @@ mod tests {
|
||||
fn test_binary_or_expression() {
|
||||
let expression = or(atomic("A"), atomic("B"));
|
||||
let header = TruthTable::extract_header(&expression);
|
||||
assert_eq!(header, vec!["A", "B", "(A ⋁ B)"]);
|
||||
assert_eq!(header, vec!["A", "B", "A ⋁ B"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -437,7 +437,7 @@ mod tests {
|
||||
fn test_complex_expression() {
|
||||
let expression = implies(and(atomic("A"), atomic("B")), or(atomic("C"), atomic("D")));
|
||||
let header = TruthTable::extract_header(&expression);
|
||||
assert_eq!(header, vec!["A", "B", "A ⋀ B", "C", "D", "(C ⋁ D)", "A ⋀ B ➔ (C ⋁ D)"]);
|
||||
assert_eq!(header, vec!["A", "B", "A ⋀ B", "C", "D", "C ⋁ D", "A ⋀ B ➔ (C ⋁ D)"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -451,6 +451,6 @@ mod tests {
|
||||
fn test_somewhat_equal() {
|
||||
let expression = and(atomic("A"), and(or(not(atomic("A")), atomic("B")), atomic("A")));
|
||||
let header = TruthTable::extract_header(&expression);
|
||||
assert_eq!(header, vec!["A", "¬A", "B", "(¬A ⋁ B)", "(¬A ⋁ B) ⋀ A", "A ⋀ (¬A ⋁ B) ⋀ A"]);
|
||||
assert_eq!(header, vec!["A", "¬A", "B", "¬A ⋁ B", "(¬A ⋁ B) ⋀ A", "A ⋀ (¬A ⋁ B) ⋀ A"]);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user