From 701328f44416b388ade2f14e7b4f4e321728b33e Mon Sep 17 00:00:00 2001 From: Tpt Date: Thu, 20 Apr 2023 16:33:40 +0200 Subject: [PATCH] Optimizer: Adds builder functions for expressions --- lib/sparopt/src/algebra.rs | 97 ++++++++++++++++++++++ lib/sparopt/src/optimizer.rs | 157 +++++++++++++---------------------- 2 files changed, 156 insertions(+), 98 deletions(-) diff --git a/lib/sparopt/src/algebra.rs b/lib/sparopt/src/algebra.rs index dd2920df..4dc15cdc 100644 --- a/lib/sparopt/src/algebra.rs +++ b/lib/sparopt/src/algebra.rs @@ -62,6 +62,103 @@ pub enum Expression { } impl Expression { + pub(crate) fn or(left: Self, right: Self) -> Self { + match ( + left.effective_boolean_value(), + right.effective_boolean_value(), + ) { + (Some(true), _) | (_, Some(true)) => true.into(), + (Some(false), Some(false)) => false.into(), + _ => Self::Or(Box::new(left), Box::new(right)), + } + } + + pub(crate) fn and(left: Self, right: Self) -> Self { + match ( + left.effective_boolean_value(), + right.effective_boolean_value(), + ) { + (Some(false), _) | (_, Some(false)) => false.into(), + (Some(true), Some(true)) => true.into(), + _ => Self::And(Box::new(left), Box::new(right)), + } + } + + pub(crate) fn equal(left: Self, right: Self) -> Self { + Self::Equal(Box::new(left), Box::new(right)) + } + + pub(crate) fn same_term(left: Self, right: Self) -> Self { + Self::SameTerm(Box::new(left), Box::new(right)) + } + + pub(crate) fn greater(left: Self, right: Self) -> Self { + Self::Greater(Box::new(left), Box::new(right)) + } + + pub(crate) fn greater_or_equal(left: Self, right: Self) -> Self { + Self::GreaterOrEqual(Box::new(left), Box::new(right)) + } + + pub(crate) fn less(left: Self, right: Self) -> Self { + Self::Less(Box::new(left), Box::new(right)) + } + + pub(crate) fn less_or_equal(left: Self, right: Self) -> Self { + Self::LessOrEqual(Box::new(left), Box::new(right)) + } + + pub(crate) fn add(left: Self, right: Self) -> Self { + Self::Add(Box::new(left), Box::new(right)) + } + + pub(crate) fn subtract(left: Self, right: Self) -> Self { + Self::Subtract(Box::new(left), Box::new(right)) + } + + pub(crate) fn multiply(left: Self, right: Self) -> Self { + Self::Multiply(Box::new(left), Box::new(right)) + } + + pub(crate) fn divide(left: Self, right: Self) -> Self { + Self::Divide(Box::new(left), Box::new(right)) + } + + pub(crate) fn unary_plus(inner: Self) -> Self { + Self::UnaryPlus(Box::new(inner)) + } + + pub(crate) fn unary_minus(inner: Self) -> Self { + Self::UnaryMinus(Box::new(inner)) + } + + pub(crate) fn not(inner: Self) -> Self { + Self::Not(Box::new(inner)) + } + + pub(crate) fn exists(inner: GraphPattern) -> Self { + if inner.is_empty() { + return false.into(); + } + Self::Exists(Box::new(inner)) + } + + pub(crate) fn if_cond(cond: Self, then: Self, els: Self) -> Self { + match cond.effective_boolean_value() { + Some(true) => then, + Some(false) => els, + None => Self::If(Box::new(cond), Box::new(then), Box::new(els)), + } + } + + pub(crate) fn coalesce(args: Vec) -> Self { + Self::Coalesce(args) + } + + pub(crate) fn call(name: Function, args: Vec) -> Self { + Self::FunctionCall(name, args) + } + pub(crate) fn effective_boolean_value(&self) -> Option { match self { Self::NamedNode(_) => Some(true), diff --git a/lib/sparopt/src/optimizer.rs b/lib/sparopt/src/optimizer.rs index b5005973..23fdc72c 100644 --- a/lib/sparopt/src/optimizer.rs +++ b/lib/sparopt/src/optimizer.rs @@ -121,111 +121,72 @@ impl Optimizer { Expression::NamedNode(node) => node.into(), Expression::Literal(literal) => literal.into(), Expression::Variable(variable) => variable.into(), - Expression::Or(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - match ( - left.effective_boolean_value(), - right.effective_boolean_value(), - ) { - (Some(true), _) | (_, Some(true)) => true.into(), - (Some(false), Some(false)) => false.into(), - _ => Expression::Or(Box::new(left), Box::new(right)), - } - } - Expression::And(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - match ( - left.effective_boolean_value(), - right.effective_boolean_value(), - ) { - (Some(false), _) | (_, Some(false)) => false.into(), - (Some(true), Some(true)) => true.into(), - _ => Expression::And(Box::new(left), Box::new(right)), - } - } - Expression::Equal(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - Expression::Equal(Box::new(left), Box::new(right)) - } - Expression::SameTerm(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - Expression::SameTerm(Box::new(left), Box::new(right)) - } - Expression::Greater(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - Expression::Greater(Box::new(left), Box::new(right)) - } - Expression::GreaterOrEqual(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - Expression::GreaterOrEqual(Box::new(left), Box::new(right)) - } - Expression::Less(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - Expression::Less(Box::new(left), Box::new(right)) - } - Expression::LessOrEqual(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - Expression::LessOrEqual(Box::new(left), Box::new(right)) - } - Expression::Add(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - Expression::Add(Box::new(left), Box::new(right)) - } - Expression::Subtract(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - Expression::Subtract(Box::new(left), Box::new(right)) - } - Expression::Multiply(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - Expression::Multiply(Box::new(left), Box::new(right)) - } - Expression::Divide(left, right) => { - let left = Self::normalize_expression(*left); - let right = Self::normalize_expression(*right); - Expression::Divide(Box::new(left), Box::new(right)) - } + Expression::Or(left, right) => Expression::or( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), + Expression::And(left, right) => Expression::and( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), + Expression::Equal(left, right) => Expression::equal( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), + Expression::SameTerm(left, right) => Expression::same_term( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), + Expression::Greater(left, right) => Expression::greater( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), + Expression::GreaterOrEqual(left, right) => Expression::greater_or_equal( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), + Expression::Less(left, right) => Expression::less( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), + Expression::LessOrEqual(left, right) => Expression::less_or_equal( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), + Expression::Add(left, right) => Expression::add( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), + Expression::Subtract(left, right) => Expression::subtract( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), + Expression::Multiply(left, right) => Expression::multiply( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), + Expression::Divide(left, right) => Expression::divide( + Self::normalize_expression(*left), + Self::normalize_expression(*right), + ), Expression::UnaryPlus(inner) => { - let inner = Self::normalize_expression(*inner); - Expression::UnaryPlus(Box::new(inner)) + Expression::unary_plus(Self::normalize_expression(*inner)) } Expression::UnaryMinus(inner) => { - let inner = Self::normalize_expression(*inner); - Expression::UnaryMinus(Box::new(inner)) - } - Expression::Not(inner) => { - let inner = Self::normalize_expression(*inner); - Expression::Not(Box::new(inner)) - } - Expression::Exists(inner) => { - let inner = Self::normalize_pattern(*inner); - Expression::Exists(Box::new(inner)) + Expression::unary_minus(Self::normalize_expression(*inner)) } + Expression::Not(inner) => Expression::not(Self::normalize_expression(*inner)), + Expression::Exists(inner) => Expression::exists(Self::normalize_pattern(*inner)), Expression::Bound(variable) => Expression::Bound(variable), - Expression::If(cond, then, els) => { - let cond = Self::normalize_expression(*cond); - let then = Self::normalize_expression(*then); - let els = Self::normalize_expression(*els); - match cond.effective_boolean_value() { - Some(true) => then, - Some(false) => els, - None => Expression::If(Box::new(cond), Box::new(then), Box::new(els)), - } - } + Expression::If(cond, then, els) => Expression::if_cond( + Self::normalize_expression(*cond), + Self::normalize_expression(*then), + Self::normalize_expression(*els), + ), Expression::Coalesce(inners) => { - Expression::Coalesce(inners.into_iter().map(Self::normalize_expression).collect()) + Expression::coalesce(inners.into_iter().map(Self::normalize_expression).collect()) } - Expression::FunctionCall(name, args) => Expression::FunctionCall( + Expression::FunctionCall(name, args) => Expression::call( name, args.into_iter().map(Self::normalize_expression).collect(), ),