Optimizer: Adds builder functions for expressions

rules
Tpt 2 years ago
parent d2d98e09e8
commit 701328f444
  1. 97
      lib/sparopt/src/algebra.rs
  2. 157
      lib/sparopt/src/optimizer.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 {
Self::Coalesce(args)
}
pub(crate) fn call(name: Function, args: Vec<Self>) -> Self {
Self::FunctionCall(name, args)
}
pub(crate) fn effective_boolean_value(&self) -> Option<bool> {
match self {
Self::NamedNode(_) => Some(true),

@ -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(),
),

Loading…
Cancel
Save