Replaced binary tuple with struct
This commit is contained in:
@ -12,7 +12,7 @@ pub trait OppositeEq {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum Expression {
|
||||
Not(Box<Expression>),
|
||||
Binary(Box<Expression>, BinaryOperator, Box<Expression>),
|
||||
Binary { left: Box<Expression>, operator: BinaryOperator, right: Box<Expression> },
|
||||
Atomic(String),
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ impl Expression {
|
||||
pub fn is_atomic(&self) -> bool {
|
||||
match self {
|
||||
Expression::Not(expr) => expr.is_atomic(),
|
||||
Expression::Binary(_, _, _) => false,
|
||||
Expression::Binary { .. } => false,
|
||||
Expression::Atomic(_) => true
|
||||
}
|
||||
}
|
||||
@ -32,7 +32,7 @@ impl Expression {
|
||||
pub fn exists(&self, atomic_value: &str) -> bool {
|
||||
match self {
|
||||
Expression::Not(expr) => expr.exists(atomic_value),
|
||||
Expression::Binary(left, _, right) => left.exists(atomic_value) || right.exists(atomic_value),
|
||||
Expression::Binary { left, right, .. } => left.exists(atomic_value) || right.exists(atomic_value),
|
||||
Expression::Atomic(value) => value == atomic_value,
|
||||
}
|
||||
}
|
||||
@ -69,14 +69,14 @@ impl Display for Expression {
|
||||
match self {
|
||||
Expression::Not(expr) if expr.is_atomic() => write!(f, "¬{expr}"),
|
||||
Expression::Not(expr) => write!(f, "¬({expr})"),
|
||||
Expression::Binary(left, BinaryOperator::And, right) => {
|
||||
Expression::Binary { left, operator: BinaryOperator::And, right } => {
|
||||
write!(f, "{left} ⋀ {right}")
|
||||
}
|
||||
// TODO do not use parentheses on root level or if several operators are on the same level
|
||||
Expression::Binary(left, BinaryOperator::Or, right) => {
|
||||
Expression::Binary { left, operator: BinaryOperator::Or, right } => {
|
||||
write!(f, "({left} ⋁ {right})")
|
||||
}
|
||||
Expression::Binary(left, BinaryOperator::Implication, right) => {
|
||||
Expression::Binary { left, operator: BinaryOperator::Implication, right } => {
|
||||
write!(f, "{left} ➔ {right}")
|
||||
}
|
||||
Expression::Atomic(value) => write!(f, "{value}"),
|
||||
|
@ -21,8 +21,8 @@ macro_rules! implies {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! binary {
|
||||
($left:expr, $op:expr, $right:expr) => {
|
||||
$crate::expressions::expression::Expression::Binary(Box::new($left), $op, Box::new($right))
|
||||
($left:expr, $operator:expr, $right:expr) => {
|
||||
$crate::expressions::expression::Expression::Binary { left: Box::new($left), operator: $operator, right: Box::new($right) }
|
||||
};
|
||||
}
|
||||
|
||||
@ -78,16 +78,16 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn eval_and() {
|
||||
assert_eq!(eval!("a" && "b"), Binary(Box::new(Atomic("a".to_string())), And, Box::new(Atomic("b".to_string()))));
|
||||
assert_eq!(eval!("a" && "b"), Binary { left: Box::new(Atomic("a".to_string())), operator: And, right: Box::new(Atomic("b".to_string())) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_or() {
|
||||
assert_eq!(eval!("a" || "b"), Binary(Box::new(Atomic("a".to_string())), Or, Box::new(Atomic("b".to_string()))));
|
||||
assert_eq!(eval!("a" || "b"), Binary { left: Box::new(Atomic("a".to_string())), operator: Or, right: Box::new(Atomic("b".to_string())) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_implies() {
|
||||
assert_eq!(eval!("a" => "b"), Binary(Box::new(Atomic("a".to_string())), Implication, Box::new(Atomic("b".to_string()))));
|
||||
assert_eq!(eval!("a" => "b"), Binary { left: Box::new(Atomic("a".to_string())), operator: Implication, right: Box::new(Atomic("b".to_string())) });
|
||||
}
|
||||
}
|
||||
|
@ -28,12 +28,12 @@ impl Simplify for Expression {
|
||||
fn elimination_of_implication(&self) -> Self {
|
||||
match self {
|
||||
Expression::Not(expr) => not!(expr.elimination_of_implication()),
|
||||
Expression::Binary(left, BinaryOperator::Implication, right) => {
|
||||
Expression::Binary { left, operator: BinaryOperator::Implication, right } => {
|
||||
let left = left.elimination_of_implication();
|
||||
let right = right.elimination_of_implication();
|
||||
or!(not!(left), right)
|
||||
}
|
||||
Expression::Binary(left, operator, right) => {
|
||||
Expression::Binary { left, operator, right } => {
|
||||
let left = left.elimination_of_implication();
|
||||
let right = right.elimination_of_implication();
|
||||
binary!(left, *operator, right)
|
||||
@ -54,7 +54,7 @@ impl Simplify for Expression {
|
||||
not!(expr.double_negation_elimination())
|
||||
}
|
||||
}
|
||||
Expression::Binary(left, operator, right) => {
|
||||
Expression::Binary { left, operator, right } => {
|
||||
let left = left.double_negation_elimination();
|
||||
let right = right.double_negation_elimination();
|
||||
binary!(left, *operator, right)
|
||||
@ -67,13 +67,13 @@ impl Simplify for Expression {
|
||||
match self {
|
||||
Expression::Not(expr) => {
|
||||
match *expr.clone() {
|
||||
Expression::Binary(left, BinaryOperator::And, right) => {
|
||||
Expression::Binary { left, operator: BinaryOperator::And, right } => {
|
||||
// TODO unnecessary cloning calls to de_morgans_laws?
|
||||
let left = not!(left.de_morgans_laws());
|
||||
let right = not!(right.de_morgans_laws());
|
||||
or!(left, right).de_morgans_laws()
|
||||
}
|
||||
Expression::Binary(left, BinaryOperator::Or, right) => {
|
||||
Expression::Binary { left, operator: BinaryOperator::Or, right } => {
|
||||
let left = not!(left.de_morgans_laws());
|
||||
let right = not!(right.de_morgans_laws());
|
||||
and!(left, right).de_morgans_laws()
|
||||
@ -81,7 +81,7 @@ impl Simplify for Expression {
|
||||
_ => not!(expr.de_morgans_laws()),
|
||||
}
|
||||
}
|
||||
Expression::Binary(left, operator, right) => {
|
||||
Expression::Binary { left, operator, right } => {
|
||||
let left = left.de_morgans_laws();
|
||||
let right = right.de_morgans_laws();
|
||||
binary!(left, *operator, right)
|
||||
@ -93,10 +93,10 @@ impl Simplify for Expression {
|
||||
// TODO deduplicate code
|
||||
fn absorption_law(&self) -> Self {
|
||||
match self {
|
||||
Expression::Binary(left, BinaryOperator::And, right) => {
|
||||
Expression::Binary { left, operator: BinaryOperator::And, right } => {
|
||||
let (left_ref, right_ref) = (left.as_ref(), right.as_ref());
|
||||
match (left_ref, right_ref) {
|
||||
(_, Expression::Binary(right_left, BinaryOperator::Or, right_right)) => {
|
||||
(_, Expression::Binary { left: right_left, operator: BinaryOperator::Or, right: right_right }) => {
|
||||
if left_ref == right_left.as_ref() || left_ref == right_right.as_ref() {
|
||||
return left.absorption_law();
|
||||
} else if right_left.is_atomic() && right_right.is_atomic() && left.opposite_eq(right_left) {
|
||||
@ -108,7 +108,7 @@ impl Simplify for Expression {
|
||||
}
|
||||
and!(left.absorption_law(), right.absorption_law())
|
||||
}
|
||||
(Expression::Binary(left_left, BinaryOperator::Or, left_right), _) => {
|
||||
(Expression::Binary { left: left_left, operator: BinaryOperator::Or, right: left_right }, _) => {
|
||||
if right_ref == left_left.as_ref() || right_ref == left_right.as_ref() {
|
||||
return right.absorption_law();
|
||||
} else if left_left.is_atomic() && left_right.is_atomic() && right.opposite_eq(left_left) {
|
||||
@ -123,10 +123,10 @@ impl Simplify for Expression {
|
||||
(left, right) => and!(left.absorption_law(), right.absorption_law())
|
||||
}
|
||||
}
|
||||
Expression::Binary(left, BinaryOperator::Or, right) => {
|
||||
Expression::Binary { left, operator: BinaryOperator::Or, right } => {
|
||||
let (left_ref, right_ref) = (left.as_ref(), right.as_ref());
|
||||
match (left_ref, right_ref) {
|
||||
(_, Expression::Binary(right_left, BinaryOperator::And, right_right)) => {
|
||||
(_, Expression::Binary { left: right_left, operator: BinaryOperator::And, right: right_right }) => {
|
||||
if left_ref == right_left.as_ref() || left_ref == right_right.as_ref() {
|
||||
return left.absorption_law();
|
||||
} else if right_left.is_atomic() && right_right.is_atomic() && left.opposite_eq(right_left) {
|
||||
@ -138,7 +138,7 @@ impl Simplify for Expression {
|
||||
}
|
||||
or!(left.absorption_law(), right.absorption_law())
|
||||
}
|
||||
(Expression::Binary(left_left, BinaryOperator::And, left_right), _) => {
|
||||
(Expression::Binary { left: left_left, operator: BinaryOperator::And, right: left_right }, _) => {
|
||||
if right_ref == left_left.as_ref() || right_ref == left_right.as_ref() {
|
||||
return right.absorption_law();
|
||||
} else if left_left.is_atomic() && left_right.is_atomic() && right.opposite_eq(left_left) {
|
||||
@ -153,7 +153,7 @@ impl Simplify for Expression {
|
||||
(left, right) => or!(left.absorption_law(), right.absorption_law())
|
||||
}
|
||||
}
|
||||
Expression::Binary(left, operator, right) => {
|
||||
Expression::Binary { left, operator, right } => {
|
||||
let left = left.absorption_law();
|
||||
let right = right.absorption_law();
|
||||
binary!(left, *operator, right)
|
||||
@ -170,14 +170,14 @@ impl Simplify for Expression {
|
||||
// TODO deduplicate code
|
||||
fn distribution_law(&self) -> Self {
|
||||
match self {
|
||||
Expression::Binary(left, BinaryOperator::And, right) => {
|
||||
Expression::Binary { left, operator: BinaryOperator::And, right } => {
|
||||
match (left.as_ref(), right.as_ref()) {
|
||||
(Expression::Atomic(_), Expression::Binary(right_left, BinaryOperator::Or, right_right)) => {
|
||||
(Expression::Atomic(_), Expression::Binary { left: right_left, operator: BinaryOperator::Or, right: right_right }) => {
|
||||
let right_left = right_left.distribution_law();
|
||||
let right_right = right_right.distribution_law();
|
||||
or!(and!(*left.clone(), right_left), and!(*left.clone(), right_right))
|
||||
}
|
||||
(Expression::Binary(left_left, BinaryOperator::Or, left_right), Expression::Atomic(_)) => {
|
||||
(Expression::Binary { left: left_left, operator: BinaryOperator::Or, right: left_right }, Expression::Atomic(_)) => {
|
||||
let left_left = left_left.distribution_law();
|
||||
let left_right = left_right.distribution_law();
|
||||
or!(and!(left_left, *right.clone()), and!(left_right, *right.clone()))
|
||||
@ -185,14 +185,14 @@ impl Simplify for Expression {
|
||||
(left, right) => and!(left.distribution_law(), right.distribution_law())
|
||||
}
|
||||
}
|
||||
Expression::Binary(left, BinaryOperator::Or, right) => {
|
||||
Expression::Binary { left, operator: BinaryOperator::Or, right } => {
|
||||
match (left.as_ref(), right.as_ref()) {
|
||||
(Expression::Atomic(_), Expression::Binary(right_left, BinaryOperator::And, right_right)) => {
|
||||
(Expression::Atomic(_), Expression::Binary { left: right_left, operator: BinaryOperator::And, right: right_right }) => {
|
||||
let right_left = right_left.distribution_law();
|
||||
let right_right = right_right.distribution_law();
|
||||
and!(or!(*left.clone(), right_left), or!(*left.clone(), right_right))
|
||||
}
|
||||
(Expression::Binary(left_left, BinaryOperator::And, left_right), Expression::Atomic(_)) => {
|
||||
(Expression::Binary { left: left_left, operator: BinaryOperator::And, right: left_right }, Expression::Atomic(_)) => {
|
||||
let left_left = left_left.distribution_law();
|
||||
let left_right = left_right.distribution_law();
|
||||
and!(or!(left_left, *right.clone()), or!(left_right, *right.clone()))
|
||||
@ -200,7 +200,7 @@ impl Simplify for Expression {
|
||||
(left, right) => or!(left.distribution_law(), right.distribution_law())
|
||||
}
|
||||
}
|
||||
Expression::Binary(left, operator, right) => {
|
||||
Expression::Binary { left, operator, right } => {
|
||||
let left = left.distribution_law();
|
||||
let right = right.distribution_law();
|
||||
binary!(left, *operator, right)
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use tokio::net::{TcpListener, ToSocketAddrs};
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
use crate::routing::{simplify, table};
|
||||
|
||||
|
Reference in New Issue
Block a user