Skip to content

Commit

Permalink
Implement math:pow() (#1549)
Browse files Browse the repository at this point in the history
Many functions from <http://www.w3.org/2005/xpath-functions/math#>, like `sqrt`, `sin`, `cos`, ... are already implemented in Qlever, but not `pow`. This PR implements `math:pow(base, exp)`.
  • Loading branch information
ullingerc authored Oct 13, 2024
1 parent 309f6b7 commit 414f50c
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/engine/sparqlExpressions/NaryExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ SparqlExpression::Ptr makeSqrtExpression(SparqlExpression::Ptr child);
SparqlExpression::Ptr makeSinExpression(SparqlExpression::Ptr child);
SparqlExpression::Ptr makeCosExpression(SparqlExpression::Ptr child);
SparqlExpression::Ptr makeTanExpression(SparqlExpression::Ptr child);
SparqlExpression::Ptr makePowExpression(SparqlExpression::Ptr child1,
SparqlExpression::Ptr child2);

SparqlExpression::Ptr makeDistExpression(SparqlExpression::Ptr child1,
SparqlExpression::Ptr child2);
Expand Down
13 changes: 13 additions & 0 deletions src/engine/sparqlExpressions/NumericBinaryExpressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Chair of Algorithms and Data Structures.
// Author: Johannes Kalmbach <[email protected]>
#include "engine/sparqlExpressions/NaryExpressionImpl.h"
#include "engine/sparqlExpressions/SparqlExpressionValueGetters.h"

namespace sparqlExpression {
namespace detail {
Expand Down Expand Up @@ -33,6 +34,13 @@ inline auto subtract = makeNumericExpression<std::minus<>>();
NARY_EXPRESSION(SubtractExpression, 2,
FV<decltype(subtract), NumericValueGetter>);

// Power.
inline auto powImpl = [](double base, double exp) {
return std::pow(base, exp);
};
inline auto pow = makeNumericExpression<decltype(powImpl)>();
NARY_EXPRESSION(PowExpression, 2, FV<decltype(pow), NumericValueGetter>);

// Or
inline auto orLambda = [](TernaryBool a, TernaryBool b) {
using enum TernaryBool;
Expand Down Expand Up @@ -96,4 +104,9 @@ SparqlExpression::Ptr makeOrExpression(SparqlExpression::Ptr child1,
SparqlExpression::Ptr child2) {
return std::make_unique<OrExpression>(std::move(child1), std::move(child2));
}

SparqlExpression::Ptr makePowExpression(SparqlExpression::Ptr child1,
SparqlExpression::Ptr child2) {
return std::make_unique<PowExpression>(std::move(child1), std::move(child2));
}
} // namespace sparqlExpression
5 changes: 5 additions & 0 deletions src/parser/sparqlParser/SparqlQleverVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "engine/sparqlExpressions/CountStarExpression.h"
#include "engine/sparqlExpressions/GroupConcatExpression.h"
#include "engine/sparqlExpressions/LiteralExpression.h"
#include "engine/sparqlExpressions/NaryExpression.h"
#include "engine/sparqlExpressions/NowDatetimeExpression.h"
#include "engine/sparqlExpressions/RandomExpression.h"
#include "engine/sparqlExpressions/RegexExpression.h"
Expand Down Expand Up @@ -131,6 +132,10 @@ ExpressionPtr Visitor::processIriFunctionCall(
} else if (functionName == "tan") {
checkNumArgs(1);
return sparqlExpression::makeTanExpression(std::move(argList[0]));
} else if (functionName == "pow") {
checkNumArgs(2);
return sparqlExpression::makePowExpression(std::move(argList[0]),
std::move(argList[1]));
}
} else if (checkPrefix(XSD_PREFIX)) {
if (functionName == "integer" || functionName == "int") {
Expand Down
18 changes: 11 additions & 7 deletions test/SparqlAntlrParserTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "engine/sparqlExpressions/CountStarExpression.h"
#include "engine/sparqlExpressions/GroupConcatExpression.h"
#include "engine/sparqlExpressions/LiteralExpression.h"
#include "engine/sparqlExpressions/NaryExpression.h"
#include "engine/sparqlExpressions/NowDatetimeExpression.h"
#include "engine/sparqlExpressions/RandomExpression.h"
#include "engine/sparqlExpressions/RegexExpression.h"
Expand Down Expand Up @@ -1669,6 +1670,9 @@ TEST(SparqlParser, FunctionCall) {
matchUnary(&makeCosExpression));
expectFunctionCall(absl::StrCat(math, "tan>(?x)"),
matchUnary(&makeTanExpression));
expectFunctionCall(
absl::StrCat(math, "pow>(?a, ?b)"),
matchNary(&makePowExpression, Variable{"?a"}, Variable{"?b"}));
expectFunctionCall(absl::StrCat(xsd, "int>(?x)"),
matchUnary(&makeConvertToIntExpression));
expectFunctionCall(absl::StrCat(xsd, "integer>(?x)"),
Expand All @@ -1679,14 +1683,14 @@ TEST(SparqlParser, FunctionCall) {
matchUnary(&makeConvertToDoubleExpression));

// Wrong number of arguments.
expectFunctionCallFails(
"<http://www.opengis.net/def/function/geosparql/distance>(?a)");
// Unknown function with the `geof:` prefix.
expectFunctionCallFails(
"<http://www.opengis.net/def/function/geosparql/notExisting>()");
expectFunctionCallFails(absl::StrCat(geof, "distance>(?a)"));
// Unknown function with `geof:`, `math:`, or `xsd:` prefix.
expectFunctionCallFails(absl::StrCat(geof, "nada>(?x)"));
expectFunctionCallFails(absl::StrCat(math, "nada>(?x)"));
expectFunctionCallFails(absl::StrCat(xsd, "nada>(?x)"));
// Prefix for which no function is known.
expectFunctionCallFails(
"<http://www.no-existing-prefixes.com/notExisting>()");
std::string prefixNexistepas = "<http://nexiste.pas/>";
expectFunctionCallFails(absl::StrCat(prefixNexistepas, "nada>(?x)"));
}

// ______________________________________________________________________________
Expand Down
3 changes: 3 additions & 0 deletions test/SparqlExpressionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,9 @@ TEST(SparqlExpression, customNumericFunctions) {
testUnaryExpression<makeTanExpression>(
std::vector<Id>{I(0), D(1), D(2), D(-1)},
std::vector<Id>{D(0), D(tan(1)), D(tan(2)), D(tan(-1))});
auto checkPow = std::bind_front(testNaryExpression, &makePowExpression);
checkPow(Ids{D(1), D(32), U, U}, Ids{I(5), D(2), U, D(0)},
IdOrLiteralOrIriVec{I(0), D(5), I(0), lit("abc")});
}

// ____________________________________________________________________________
Expand Down

0 comments on commit 414f50c

Please sign in to comment.