From 3bfc7942e204469ed7b79217d03b30461443d7f1 Mon Sep 17 00:00:00 2001 From: fintarin Date: Sun, 3 Mar 2024 16:12:12 +0300 Subject: [PATCH] Add new functions and rework operators --- include/fintamath/core/MathObjectType.hpp | 29 +-- include/fintamath/expressions/Expression.hpp | 9 +- .../expressions/ExpressionComparator.hpp | 2 +- .../fintamath/expressions/ExpressionUtils.hpp | 2 + include/fintamath/functions/IFunctionCRTP.hpp | 19 +- .../fintamath/functions/arithmetic/Add.hpp | 12 +- .../functions/arithmetic/AddOper.hpp | 36 ++++ .../fintamath/functions/arithmetic/Mul.hpp | 12 +- .../functions/arithmetic/MulOper.hpp | 36 ++++ include/fintamath/functions/logic/And.hpp | 11 +- include/fintamath/functions/logic/AndOper.hpp | 36 ++++ include/fintamath/functions/logic/Or.hpp | 12 +- include/fintamath/functions/logic/OrOper.hpp | 38 ++++ include/fintamath/functions/powers/Pow.hpp | 8 +- .../powers/{PowFunction.hpp => PowOper.hpp} | 15 +- src/fintamath/config/ExpressionConfig.cpp | 34 ++- src/fintamath/config/ParserConfig.cpp | 34 +-- src/fintamath/expressions/Expression.cpp | 8 +- .../expressions/ExpressionComparator.cpp | 204 ++++++------------ src/fintamath/expressions/ExpressionUtils.cpp | 24 ++- .../expressions/FunctionExpression.cpp | 21 +- .../expressions/FunctionExpression.hpp | 3 + src/fintamath/expressions/binary/PowExpr.cpp | 43 ++-- src/fintamath/expressions/binary/PowExpr.hpp | 4 +- .../interfaces/IBinaryExpression.cpp | 9 +- .../interfaces/IPolynomExpression.cpp | 22 +- .../interfaces/IUnaryExpression.cpp | 15 +- .../expressions/polynomial/AddExpr.cpp | 8 +- .../expressions/polynomial/AddExpr.hpp | 2 + .../expressions/polynomial/AndExpr.cpp | 6 + .../expressions/polynomial/AndExpr.hpp | 2 + .../expressions/polynomial/MulExpr.cpp | 6 + .../expressions/polynomial/MulExpr.hpp | 3 + .../expressions/polynomial/OrExpr.cpp | 6 + .../expressions/polynomial/OrExpr.hpp | 2 + .../functions/arithmetic/AddOper.cpp | 15 ++ .../functions/arithmetic/MulOper.cpp | 15 ++ src/fintamath/functions/logic/AndOper.cpp | 15 ++ src/fintamath/functions/logic/OrOper.cpp | 15 ++ .../powers/{PowFunction.cpp => PowOper.cpp} | 4 +- tests/src/core/ParseTests.cpp | 24 ++- .../interfaces/IBinaryExpressionTests.cpp | 4 +- .../interfaces/IPolynomExpressionTests.cpp | 8 +- tests/src/functions/IOperatorTests.cpp | 15 +- .../src/functions/arithmetic/AddOperTests.cpp | 65 ++++++ tests/src/functions/arithmetic/AddTests.cpp | 12 +- .../src/functions/arithmetic/MulOperTests.cpp | 63 ++++++ tests/src/functions/arithmetic/MulTests.cpp | 12 +- tests/src/functions/logic/AndOperTests.cpp | 62 ++++++ tests/src/functions/logic/AndTests.cpp | 12 +- tests/src/functions/logic/OrOperTests.cpp | 62 ++++++ tests/src/functions/logic/OrTests.cpp | 12 +- ...{PowFunctionTests.cpp => PowOperTests.cpp} | 43 ++-- tests/src/functions/powers/PowTests.cpp | 12 +- 54 files changed, 817 insertions(+), 386 deletions(-) create mode 100644 include/fintamath/functions/arithmetic/AddOper.hpp create mode 100644 include/fintamath/functions/arithmetic/MulOper.hpp create mode 100644 include/fintamath/functions/logic/AndOper.hpp create mode 100644 include/fintamath/functions/logic/OrOper.hpp rename include/fintamath/functions/powers/{PowFunction.hpp => PowOper.hpp} (59%) create mode 100644 src/fintamath/functions/arithmetic/AddOper.cpp create mode 100644 src/fintamath/functions/arithmetic/MulOper.cpp create mode 100644 src/fintamath/functions/logic/AndOper.cpp create mode 100644 src/fintamath/functions/logic/OrOper.cpp rename src/fintamath/functions/powers/{PowFunction.cpp => PowOper.cpp} (60%) create mode 100644 tests/src/functions/arithmetic/AddOperTests.cpp create mode 100644 tests/src/functions/arithmetic/MulOperTests.cpp create mode 100644 tests/src/functions/logic/AndOperTests.cpp create mode 100644 tests/src/functions/logic/OrOperTests.cpp rename tests/src/functions/powers/{PowFunctionTests.cpp => PowOperTests.cpp} (51%) diff --git a/include/fintamath/core/MathObjectType.hpp b/include/fintamath/core/MathObjectType.hpp index 7b297e62d..f0ce5e2ad 100644 --- a/include/fintamath/core/MathObjectType.hpp +++ b/include/fintamath/core/MathObjectType.hpp @@ -79,6 +79,9 @@ struct MathObjectType final { IFunction = 11000, + Add, + Mul, + Pow, Abs, Log, Ln, @@ -119,21 +122,25 @@ struct MathObjectType final { Integral, Frac, FracMixed, - PowFunction, Floor, Ceil, + And, + Or, IOperator = 12000, - - Add, + AddOper, + UnaryPlus, Sub, - Mul, - Div, Neg, - UnaryPlus, + MulOper, + Div, + Mod, + PowOper, Factorial, Percent, - Pow, + Deg, + Index, + Comma, Eqv, Neqv, Less, @@ -141,15 +148,11 @@ struct MathObjectType final { LessEqv, MoreEqv, Not, - And, - Or, + AndOper, + OrOper, Impl, Equiv, Nequiv, - Index, - Deg, - Comma, - Mod, None = std::numeric_limits::max(), }; diff --git a/include/fintamath/expressions/Expression.hpp b/include/fintamath/expressions/Expression.hpp index 976a3e56f..087cc58ae 100644 --- a/include/fintamath/expressions/Expression.hpp +++ b/include/fintamath/expressions/Expression.hpp @@ -92,7 +92,7 @@ class Expression final : public IExpressionCRTP { getTermParser().registerType(std::move(constructor)); } - template + template static void registerFunctionExpressionMaker(ExpressionMaker maker); static constexpr MathObjectType getTypeStatic() { @@ -195,7 +195,7 @@ Expression operator/(const Expression &lhs, const Variable &rhs); Expression operator/(const Variable &lhs, const Expression &rhs); -template +template void Expression::registerFunctionExpressionMaker(ExpressionMaker maker) { ExpressionParser::Constructor constructor = [maker = std::move(maker)](ArgumentPtrVector &&args) { static const size_t argSize = Function{}.getArgumentTypes().size(); @@ -204,11 +204,6 @@ void Expression::registerFunctionExpressionMaker(ExpressionMaker maker) { if constexpr (Function::isVariadicStatic()) { res = maker(std::move(args)); } - else if constexpr (isPolynomial) { - if (argSize <= args.size()) { - res = maker(std::move(args)); - } - } else { if (argSize == args.size()) { res = maker(std::move(args)); diff --git a/include/fintamath/expressions/ExpressionComparator.hpp b/include/fintamath/expressions/ExpressionComparator.hpp index c40667723..3c503800c 100644 --- a/include/fintamath/expressions/ExpressionComparator.hpp +++ b/include/fintamath/expressions/ExpressionComparator.hpp @@ -7,7 +7,7 @@ namespace fintamath::detail { struct ComparatorOptions final { - bool constantGreaterThanVariable = false; + bool termOrderInversed = false; bool comparableOrderInversed = false; }; diff --git a/include/fintamath/expressions/ExpressionUtils.hpp b/include/fintamath/expressions/ExpressionUtils.hpp index 277b34de9..12aa676ab 100644 --- a/include/fintamath/expressions/ExpressionUtils.hpp +++ b/include/fintamath/expressions/ExpressionUtils.hpp @@ -76,6 +76,8 @@ std::pair splitRational(const ArgumentPtr &arg); ArgumentPtr negate(const ArgumentPtr &arg); +ArgumentPtr invert(const ArgumentPtr &arg); + ArgumentPtr makePolynom(const IFunction &func, ArgumentPtrVector &&args); ArgumentPtr makePolynom(const IFunction &func, const ArgumentPtrVector &args); diff --git a/include/fintamath/functions/IFunctionCRTP.hpp b/include/fintamath/functions/IFunctionCRTP.hpp index 89b6ab255..a84962afb 100644 --- a/include/fintamath/functions/IFunctionCRTP.hpp +++ b/include/fintamath/functions/IFunctionCRTP.hpp @@ -29,7 +29,7 @@ class IFunctionCRTP_ : public IFunction { bool doArgsMatch(const ArgumentRefVector &argVect) const override { if constexpr (Derived::isVariadicStatic()) { - return doAnyArgsMatch(argVect); + return doVariadicArgsMatch(argVect); } else { if (argVect.size() != argTypes.size()) { @@ -80,8 +80,8 @@ class IFunctionCRTP_ : public IFunction { private: template - bool doArgsMatch(const ArgumentRefVector &argVect) const { - if (!is(argVect[i]) || detail::isExpression(argVect[i])) { + static bool doArgsMatch(const ArgumentRefVector &argVect) { + if (!doArgMatch(argVect[i])) { return false; } @@ -89,18 +89,23 @@ class IFunctionCRTP_ : public IFunction { } template - bool doArgsMatch(const ArgumentRefVector & /*unused*/) const { + static bool doArgsMatch(const ArgumentRefVector &) { return true; } - bool doAnyArgsMatch(const ArgumentRefVector &argVect) const { - using AnyArgsType = typename std::tuple_element_t<0, std::tuple>; + static bool doVariadicArgsMatch(const ArgumentRefVector &argVect) { + using ExpectedArg = typename std::tuple_element_t<0, std::tuple>; return stdr::all_of(argVect, [](const auto &arg) { - return is(arg); + return doArgMatch(arg); }); } + template + static bool doArgMatch(const ArgumentRef &arg) { + return is(arg) && !detail::isExpression(arg); + } + private: inline static const ArgumentTypeVector argTypes = {Args::getTypeStatic()...}; diff --git a/include/fintamath/functions/arithmetic/Add.hpp b/include/fintamath/functions/arithmetic/Add.hpp index c440491d6..b2e43ab61 100644 --- a/include/fintamath/functions/arithmetic/Add.hpp +++ b/include/fintamath/functions/arithmetic/Add.hpp @@ -8,24 +8,20 @@ #include "fintamath/core/MathObjectType.hpp" #include "fintamath/functions/FunctionArguments.hpp" #include "fintamath/functions/FunctionUtils.hpp" -#include "fintamath/functions/IOperator.hpp" +#include "fintamath/functions/IFunction.hpp" namespace fintamath { -class Add final : public IOperatorCRTP { +class Add final : public IFunctionCRTP { public: std::string toString() const override { - return "+"; + return "add"; } - static constexpr bool isAssociativeStatic() { + static constexpr bool isVariadicStatic() { return true; } - static constexpr Priority getPriorityStatic() { - return Priority::Addition; - } - static constexpr MathObjectType getTypeStatic() { return {MathObjectType::Add, "Add"}; } diff --git a/include/fintamath/functions/arithmetic/AddOper.hpp b/include/fintamath/functions/arithmetic/AddOper.hpp new file mode 100644 index 000000000..ab2abfcb8 --- /dev/null +++ b/include/fintamath/functions/arithmetic/AddOper.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +#include "fintamath/core/IArithmetic.hpp" +#include "fintamath/core/IMathObject.hpp" +#include "fintamath/core/MathObjectType.hpp" +#include "fintamath/functions/FunctionArguments.hpp" +#include "fintamath/functions/IOperator.hpp" + +namespace fintamath { + +class AddOper final : public IOperatorCRTP { +public: + std::string toString() const override { + return "+"; + } + + static constexpr bool isAssociativeStatic() { + return true; + } + + static constexpr Priority getPriorityStatic() { + return Priority::Addition; + } + + static constexpr MathObjectType getTypeStatic() { + return {MathObjectType::AddOper, "AddOper"}; + } + +protected: + std::unique_ptr call(const ArgumentRefVector &argVect) const override; +}; + +} diff --git a/include/fintamath/functions/arithmetic/Mul.hpp b/include/fintamath/functions/arithmetic/Mul.hpp index 49a8c84ac..f4d199892 100644 --- a/include/fintamath/functions/arithmetic/Mul.hpp +++ b/include/fintamath/functions/arithmetic/Mul.hpp @@ -8,24 +8,20 @@ #include "fintamath/core/MathObjectType.hpp" #include "fintamath/functions/FunctionArguments.hpp" #include "fintamath/functions/FunctionUtils.hpp" -#include "fintamath/functions/IOperator.hpp" +#include "fintamath/functions/IFunction.hpp" namespace fintamath { -class Mul final : public IOperatorCRTP { +class Mul final : public IFunctionCRTP { public: std::string toString() const override { - return "*"; + return "mul"; } - static constexpr bool isAssociativeStatic() { + static constexpr bool isVariadicStatic() { return true; } - static constexpr Priority getPriorityStatic() { - return Priority::Multiplication; - } - static constexpr MathObjectType getTypeStatic() { return {MathObjectType::Mul, "Mul"}; } diff --git a/include/fintamath/functions/arithmetic/MulOper.hpp b/include/fintamath/functions/arithmetic/MulOper.hpp new file mode 100644 index 000000000..35e5f738b --- /dev/null +++ b/include/fintamath/functions/arithmetic/MulOper.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +#include "fintamath/core/IArithmetic.hpp" +#include "fintamath/core/IMathObject.hpp" +#include "fintamath/core/MathObjectType.hpp" +#include "fintamath/functions/FunctionArguments.hpp" +#include "fintamath/functions/IOperator.hpp" + +namespace fintamath { + +class MulOper final : public IOperatorCRTP { +public: + std::string toString() const override { + return "*"; + } + + static constexpr bool isAssociativeStatic() { + return true; + } + + static constexpr Priority getPriorityStatic() { + return Priority::Multiplication; + } + + static constexpr MathObjectType getTypeStatic() { + return {MathObjectType::MulOper, "MulOper"}; + } + +protected: + std::unique_ptr call(const ArgumentRefVector &argVect) const override; +}; + +} diff --git a/include/fintamath/functions/logic/And.hpp b/include/fintamath/functions/logic/And.hpp index fd15849c6..093dbd87b 100644 --- a/include/fintamath/functions/logic/And.hpp +++ b/include/fintamath/functions/logic/And.hpp @@ -7,25 +7,22 @@ #include "fintamath/core/MathObjectType.hpp" #include "fintamath/functions/FunctionArguments.hpp" #include "fintamath/functions/FunctionUtils.hpp" +#include "fintamath/functions/IFunction.hpp" #include "fintamath/functions/IOperator.hpp" #include "fintamath/literals/Boolean.hpp" namespace fintamath { -class And final : public IOperatorCRTP { +class And final : public IFunctionCRTP { public: std::string toString() const override { - return "&"; + return "and"; } - static constexpr bool isAssociativeStatic() { + static constexpr bool isVariadicStatic() { return true; } - static constexpr Priority getPriorityStatic() { - return Priority::Conjunction; - } - static constexpr MathObjectType getTypeStatic() { return {MathObjectType::And, "And"}; } diff --git a/include/fintamath/functions/logic/AndOper.hpp b/include/fintamath/functions/logic/AndOper.hpp new file mode 100644 index 000000000..05e028e40 --- /dev/null +++ b/include/fintamath/functions/logic/AndOper.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +#include "fintamath/core/IMathObject.hpp" +#include "fintamath/core/MathObjectType.hpp" +#include "fintamath/functions/FunctionArguments.hpp" +#include "fintamath/functions/IOperator.hpp" +#include "fintamath/literals/Boolean.hpp" + +namespace fintamath { + +class AndOper final : public IOperatorCRTP { +public: + std::string toString() const override { + return "&"; + } + + static constexpr bool isAssociativeStatic() { + return true; + } + + static constexpr Priority getPriorityStatic() { + return Priority::Conjunction; + } + + static constexpr MathObjectType getTypeStatic() { + return {MathObjectType::AndOper, "AndOper"}; + } + +protected: + std::unique_ptr call(const ArgumentRefVector &argVect) const override; +}; + +} diff --git a/include/fintamath/functions/logic/Or.hpp b/include/fintamath/functions/logic/Or.hpp index 49c97f146..88cae2a89 100644 --- a/include/fintamath/functions/logic/Or.hpp +++ b/include/fintamath/functions/logic/Or.hpp @@ -7,25 +7,21 @@ #include "fintamath/core/MathObjectType.hpp" #include "fintamath/functions/FunctionArguments.hpp" #include "fintamath/functions/FunctionUtils.hpp" -#include "fintamath/functions/IOperator.hpp" +#include "fintamath/functions/IFunction.hpp" #include "fintamath/literals/Boolean.hpp" namespace fintamath { -class Or final : public IOperatorCRTP { +class Or final : public IFunctionCRTP { public: std::string toString() const override { - return "|"; + return "or"; } - static constexpr bool isAssociativeStatic() { + static constexpr bool isVariadicStatic() { return true; } - static constexpr Priority getPriorityStatic() { - return Priority::Disjunction; - } - static constexpr MathObjectType getTypeStatic() { return {MathObjectType::Or, "Or"}; } diff --git a/include/fintamath/functions/logic/OrOper.hpp b/include/fintamath/functions/logic/OrOper.hpp new file mode 100644 index 000000000..cf702830b --- /dev/null +++ b/include/fintamath/functions/logic/OrOper.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +#include "fintamath/core/IMathObject.hpp" +#include "fintamath/core/MathObjectType.hpp" +#include "fintamath/functions/FunctionArguments.hpp" +#include "fintamath/functions/FunctionUtils.hpp" +#include "fintamath/functions/IFunction.hpp" +#include "fintamath/functions/IOperator.hpp" +#include "fintamath/literals/Boolean.hpp" + +namespace fintamath { + +class OrOper final : public IOperatorCRTP { +public: + std::string toString() const override { + return "|"; + } + + static constexpr bool isAssociativeStatic() { + return true; + } + + static constexpr Priority getPriorityStatic() { + return Priority::Disjunction; + } + + static constexpr MathObjectType getTypeStatic() { + return {MathObjectType::OrOper, "OrOper"}; + } + +protected: + std::unique_ptr call(const ArgumentRefVector &argVect) const override; +}; + +} diff --git a/include/fintamath/functions/powers/Pow.hpp b/include/fintamath/functions/powers/Pow.hpp index e36058302..206a3b5cf 100644 --- a/include/fintamath/functions/powers/Pow.hpp +++ b/include/fintamath/functions/powers/Pow.hpp @@ -17,14 +17,10 @@ class Rational; class Real; class Complex; -class Pow final : public IOperatorCRTP { +class Pow final : public IFunctionCRTP { public: std::string toString() const override { - return "^"; - } - - static constexpr Priority getPriorityStatic() { - return Priority::Exponentiation; + return "pow"; } static constexpr MathObjectType getTypeStatic() { diff --git a/include/fintamath/functions/powers/PowFunction.hpp b/include/fintamath/functions/powers/PowOper.hpp similarity index 59% rename from include/fintamath/functions/powers/PowFunction.hpp rename to include/fintamath/functions/powers/PowOper.hpp index d255a54fe..921326063 100644 --- a/include/fintamath/functions/powers/PowFunction.hpp +++ b/include/fintamath/functions/powers/PowOper.hpp @@ -7,22 +7,27 @@ #include "fintamath/core/IMathObject.hpp" #include "fintamath/core/MathObjectType.hpp" #include "fintamath/functions/FunctionArguments.hpp" -#include "fintamath/functions/IFunction.hpp" +#include "fintamath/functions/IOperator.hpp" +#include "fintamath/numbers/INumber.hpp" namespace fintamath { -class PowFunction final : public IFunctionCRTP { +class PowOper final : public IOperatorCRTP { public: std::string toString() const override { - return "pow"; + return "^"; + } + + static constexpr Priority getPriorityStatic() { + return Priority::Exponentiation; } static constexpr MathObjectType getTypeStatic() { - return {MathObjectType::PowFunction, "PowFunction"}; + return {MathObjectType::PowOper, "PowOper"}; } protected: std::unique_ptr call(const ArgumentRefVector &argVect) const override; }; -} +} \ No newline at end of file diff --git a/src/fintamath/config/ExpressionConfig.cpp b/src/fintamath/config/ExpressionConfig.cpp index 623ddc51d..44ea3cec9 100644 --- a/src/fintamath/config/ExpressionConfig.cpp +++ b/src/fintamath/config/ExpressionConfig.cpp @@ -29,10 +29,12 @@ #include "fintamath/functions/IFunction.hpp" #include "fintamath/functions/arithmetic/Abs.hpp" #include "fintamath/functions/arithmetic/Add.hpp" +#include "fintamath/functions/arithmetic/AddOper.hpp" #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Frac.hpp" #include "fintamath/functions/arithmetic/FracMixed.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" +#include "fintamath/functions/arithmetic/MulOper.hpp" #include "fintamath/functions/arithmetic/Neg.hpp" #include "fintamath/functions/arithmetic/Sign.hpp" #include "fintamath/functions/arithmetic/Sub.hpp" @@ -64,11 +66,13 @@ #include "fintamath/functions/logarithms/Ln.hpp" #include "fintamath/functions/logarithms/Log.hpp" #include "fintamath/functions/logic/And.hpp" +#include "fintamath/functions/logic/AndOper.hpp" #include "fintamath/functions/logic/Equiv.hpp" #include "fintamath/functions/logic/Impl.hpp" #include "fintamath/functions/logic/Nequiv.hpp" #include "fintamath/functions/logic/Not.hpp" #include "fintamath/functions/logic/Or.hpp" +#include "fintamath/functions/logic/OrOper.hpp" #include "fintamath/functions/ntheory/Ceil.hpp" #include "fintamath/functions/ntheory/Floor.hpp" #include "fintamath/functions/other/Deg.hpp" @@ -76,7 +80,7 @@ #include "fintamath/functions/other/Percent.hpp" #include "fintamath/functions/powers/Exp.hpp" #include "fintamath/functions/powers/Pow.hpp" -#include "fintamath/functions/powers/PowFunction.hpp" +#include "fintamath/functions/powers/PowOper.hpp" #include "fintamath/functions/powers/Root.hpp" #include "fintamath/functions/powers/Sqr.hpp" #include "fintamath/functions/powers/Sqrt.hpp" @@ -134,23 +138,31 @@ void registerTermParsers() { } void registerFunctionExpressionMakers() { - Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { return AddExpr(std::move(args)).clone(); }); + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { + return addExpr(std::move(args)); + }); + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector args) { ArgumentPtr lhs = std::move(args.front()); ArgumentPtr rhs = std::move(args.back()); ArgumentPtr negRhs = negExpr(std::move(rhs)); - return AddExpr({std::move(lhs), std::move(negRhs)}).clone(); + return addExpr(std::move(lhs), std::move(negRhs)); }); - Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { return MulExpr(std::move(args)).clone(); }); + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { + return mulExpr(std::move(args)); + }); + Expression::registerFunctionExpressionMaker
([](ArgumentPtrVector args) { return DivExpr(std::move(args.front()), std::move(args.back())).clone(); }); @@ -167,19 +179,27 @@ void registerFunctionExpressionMakers() { return addExpr(std::move(integ), divExpr(std::move(numer), std::move(denom))); }); - Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { return AndExpr(std::move(args)).clone(); }); - Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { + return andExpr(std::move(args)); + }); + + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { return OrExpr(std::move(args)).clone(); }); + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { + return orExpr(std::move(args)); + }); + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector args) { return PowExpr(std::move(args.front()), std::move(args.back())).clone(); }); - Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { return powExpr(std::move(args)); }); diff --git a/src/fintamath/config/ParserConfig.cpp b/src/fintamath/config/ParserConfig.cpp index f37e33f3f..752588bcd 100644 --- a/src/fintamath/config/ParserConfig.cpp +++ b/src/fintamath/config/ParserConfig.cpp @@ -11,10 +11,12 @@ #include "fintamath/functions/IOperator.hpp" #include "fintamath/functions/arithmetic/Abs.hpp" #include "fintamath/functions/arithmetic/Add.hpp" +#include "fintamath/functions/arithmetic/AddOper.hpp" #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Frac.hpp" #include "fintamath/functions/arithmetic/FracMixed.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" +#include "fintamath/functions/arithmetic/MulOper.hpp" #include "fintamath/functions/arithmetic/Neg.hpp" #include "fintamath/functions/arithmetic/Sign.hpp" #include "fintamath/functions/arithmetic/Sub.hpp" @@ -46,11 +48,13 @@ #include "fintamath/functions/logarithms/Ln.hpp" #include "fintamath/functions/logarithms/Log.hpp" #include "fintamath/functions/logic/And.hpp" +#include "fintamath/functions/logic/AndOper.hpp" #include "fintamath/functions/logic/Equiv.hpp" #include "fintamath/functions/logic/Impl.hpp" #include "fintamath/functions/logic/Nequiv.hpp" #include "fintamath/functions/logic/Not.hpp" #include "fintamath/functions/logic/Or.hpp" +#include "fintamath/functions/logic/OrOper.hpp" #include "fintamath/functions/ntheory/Ceil.hpp" #include "fintamath/functions/ntheory/Floor.hpp" #include "fintamath/functions/ntheory/Mod.hpp" @@ -61,7 +65,7 @@ #include "fintamath/functions/other/Percent.hpp" #include "fintamath/functions/powers/Exp.hpp" #include "fintamath/functions/powers/Pow.hpp" -#include "fintamath/functions/powers/PowFunction.hpp" +#include "fintamath/functions/powers/PowOper.hpp" #include "fintamath/functions/powers/Root.hpp" #include "fintamath/functions/powers/Sqr.hpp" #include "fintamath/functions/powers/Sqrt.hpp" @@ -126,6 +130,9 @@ ParserConfig::ParserConfig() { IConstant::registerType(); IConstant::registerType(); + IFunction::registerType(); + IFunction::registerType(); + IFunction::registerType(); IFunction::registerType(); IFunction::registerType(); IFunction::registerType(); @@ -166,19 +173,24 @@ ParserConfig::ParserConfig() { IFunction::registerType(); IFunction::registerType(); IFunction::registerType(); - IFunction::registerType(); IFunction::registerType(); IFunction::registerType(); + IFunction::registerType(); + IFunction::registerType(); - IOperator::registerType(); + IOperator::registerType(); + IOperator::registerType(); IOperator::registerType(); - IOperator::registerType(); - IOperator::registerType
(); IOperator::registerType(); - IOperator::registerType(); + IOperator::registerType(); + IOperator::registerType
(); + IOperator::registerType(); + IOperator::registerType(); IOperator::registerType(); IOperator::registerType(); - IOperator::registerType(); + IOperator::registerType(); + IOperator::registerType(); + IOperator::registerType(); IOperator::registerType(); IOperator::registerType(); IOperator::registerType(); @@ -186,15 +198,11 @@ ParserConfig::ParserConfig() { IOperator::registerType(); IOperator::registerType(); IOperator::registerType(); - IOperator::registerType(); - IOperator::registerType(); + IOperator::registerType(); + IOperator::registerType(); IOperator::registerType(); IOperator::registerType(); IOperator::registerType(); - IOperator::registerType(); - IOperator::registerType(); - IOperator::registerType(); - IOperator::registerType(); IExpression::registerType(); } diff --git a/src/fintamath/expressions/Expression.cpp b/src/fintamath/expressions/Expression.cpp index 534ee631e..b06b6b8d5 100644 --- a/src/fintamath/expressions/Expression.cpp +++ b/src/fintamath/expressions/Expression.cpp @@ -28,6 +28,7 @@ #include "fintamath/functions/arithmetic/Add.hpp" #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" +#include "fintamath/functions/arithmetic/MulOper.hpp" #include "fintamath/functions/arithmetic/Neg.hpp" #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/other/Comma.hpp" @@ -295,7 +296,7 @@ void Expression::moveFunctionsToOperands(OperandStack &operands, std::stack makeExpr(const IFunction &func, ArgumentPtrVector args) { stdr::transform(args, args.begin(), &Expression::compress); + + if (func.isVariadic() && args.size() == 1) { + return std::move(args.front())->clone(); + } + Expression::validateFunctionArgs(func, args); if (auto expr = Expression::getExpressionParser().parse(func.toString(), std::move(args))) { diff --git a/src/fintamath/expressions/ExpressionComparator.cpp b/src/fintamath/expressions/ExpressionComparator.cpp index c98c463c0..67af59ff8 100644 --- a/src/fintamath/expressions/ExpressionComparator.cpp +++ b/src/fintamath/expressions/ExpressionComparator.cpp @@ -16,12 +16,18 @@ #include "fintamath/functions/FunctionArguments.hpp" #include "fintamath/functions/FunctionUtils.hpp" #include "fintamath/functions/IFunction.hpp" +#include "fintamath/functions/arithmetic/Mul.hpp" +#include "fintamath/functions/powers/Pow.hpp" #include "fintamath/literals/ILiteral.hpp" #include "fintamath/literals/Variable.hpp" namespace fintamath::detail { -using ExpressionTreePathStack = std::stack, size_t>>; +using ExpressionPtr = std::shared_ptr; + +using PolynomPtr = std::shared_ptr; + +using ExpressionTreePath = std::stack>; using Ordering = std::strong_ordering; @@ -35,33 +41,19 @@ struct ChildrenComparatorResult final { Ordering size = Ordering::equal; }; -Ordering compareNonExpressions(const ArgumentPtr &lhs, - const ArgumentPtr &rhs, - const ComparatorOptions &options); +Ordering compareNonExpressions(const ArgumentPtr &lhs, const ArgumentPtr &rhs, const ComparatorOptions &options); -Ordering comparePolynoms(const std::shared_ptr &lhs, - const std::shared_ptr &rhs, - const ComparatorOptions &options); +Ordering comparePolynoms(const PolynomPtr &lhs, const PolynomPtr &rhs, const ComparatorOptions &options); -Ordering compareExpressions(const std::shared_ptr &lhs, - const std::shared_ptr &rhs, - const ComparatorOptions &options); +Ordering compareExpressions(const ExpressionPtr &lhs, const ExpressionPtr &rhs, const ComparatorOptions &options); -Ordering comparePolynomAndNonPolynom(const std::shared_ptr &lhs, - const ArgumentPtr &rhs, - const ComparatorOptions &options); +Ordering comparePolynomAndNonPolynom(const PolynomPtr &lhs, const ArgumentPtr &rhs, const ComparatorOptions &options); -Ordering compareExpressionAndNonExpression(const std::shared_ptr &lhs, - const ArgumentPtr &rhs, - const ComparatorOptions &options); +Ordering compareExpressionAndNonExpression(const ExpressionPtr &lhs, const ArgumentPtr &rhs, const ComparatorOptions &options); -Ordering compareFunctions(const std::shared_ptr &lhs, - const std::shared_ptr &rhs, - const ComparatorOptions &options); +Ordering compareFunctions(const std::shared_ptr &lhs, const std::shared_ptr &rhs); -ChildrenComparatorResult compareChildren(const ArgumentPtrVector &lhsChildren, - const ArgumentPtrVector &rhsChildren, - const ComparatorOptions &options); +ChildrenComparatorResult compareChildren(const ArgumentPtrVector &lhsChildren, const ArgumentPtrVector &rhsChildren, const ComparatorOptions &options); bool unwrapUnaryExpression(ArgumentPtr &arg); @@ -80,25 +72,25 @@ size_t getPositionOfFirstChildWithTerm(const ArgumentPtrVector &children) { return children.size(); } -template -std::shared_ptr popNextTerm(ExpressionTreePathStack &stack) { - while (!stack.empty()) { - const ArgumentPtrVector &children = stack.top().first->getChildren(); +template +std::shared_ptr popNextTerm(ExpressionTreePath &path) { + while (!path.empty()) { + const ArgumentPtrVector &children = path.top().first->getChildren(); // TODO: looks weird - size_t &exprIndex = stack.top().second; + size_t &exprIndex = path.top().second; exprIndex++; bool hasExprChild = false; for (; exprIndex < children.size(); exprIndex++) { if (const auto &exprChild = cast(children[exprIndex]); exprChild && containsVariable(exprChild)) { - stack.emplace(exprChild, -1); + path.emplace(exprChild, -1); hasExprChild = true; break; } - if (const auto &varChild = cast(children[exprIndex])) { + if (const auto &varChild = cast(children[exprIndex])) { return varChild; } } @@ -107,45 +99,42 @@ std::shared_ptr popNextTerm(ExpressionTreePathStack &stack) { continue; } - stack.pop(); + path.pop(); } return {}; } -template -Ordering compareTerms(const ArgumentPtr &lhs, - const ArgumentPtr &rhs, - const ComparatorOptions &options) { - - ExpressionTreePathStack lhsPath; - ExpressionTreePathStack rhsPath; +template +Ordering compareTerms(const ArgumentPtr &lhs, const ArgumentPtr &rhs, const ComparatorOptions &options) { + ExpressionTreePath lhsPath; + ExpressionTreePath rhsPath; - std::shared_ptr lhsTerm; - std::shared_ptr rhsTerm; + std::shared_ptr lhsTerm; + std::shared_ptr rhsTerm; if (const auto &expr = cast(lhs)) { lhsPath.emplace(expr, -1); - lhsTerm = popNextTerm(lhsPath); + lhsTerm = popNextTerm(lhsPath); } - else if (const auto &term = cast(lhs)) { + else if (const auto &term = cast(lhs)) { lhsTerm = term; } if (const auto &expr = cast(rhs)) { rhsPath.emplace(expr, -1); - rhsTerm = popNextTerm(rhsPath); + rhsTerm = popNextTerm(rhsPath); } - else if (const auto &term = cast(rhs)) { + else if (const auto &term = cast(rhs)) { rhsTerm = term; } if (lhsTerm && !rhsTerm) { - return !options.constantGreaterThanVariable ? Ordering::greater : Ordering::less; + return !options.termOrderInversed ? Ordering::greater : Ordering::less; } if (!lhsTerm && rhsTerm) { - return options.constantGreaterThanVariable ? Ordering::greater : Ordering::less; + return options.termOrderInversed ? Ordering::greater : Ordering::less; } while (lhsTerm && rhsTerm) { @@ -153,17 +142,14 @@ Ordering compareTerms(const ArgumentPtr &lhs, return res; } - lhsTerm = popNextTerm(lhsPath); - rhsTerm = popNextTerm(rhsPath); + lhsTerm = popNextTerm(lhsPath); + rhsTerm = popNextTerm(rhsPath); } return Ordering::equal; } -Ordering compare(ArgumentPtr lhs, - ArgumentPtr rhs, - const ComparatorOptions options) { - +Ordering compare(ArgumentPtr lhs, ArgumentPtr rhs, const ComparatorOptions options) { unwrapEmptyExpression(lhs); unwrapEmptyExpression(rhs); @@ -200,22 +186,19 @@ Ordering compare(ArgumentPtr lhs, return compareExpressions(lhsExpr, rhsExpr, options); } -Ordering compareNonExpressions(const ArgumentPtr &lhs, - const ArgumentPtr &rhs, - const ComparatorOptions &options) { - +Ordering compareNonExpressions(const ArgumentPtr &lhs, const ArgumentPtr &rhs, const ComparatorOptions &options) { if (is(lhs) && !is(rhs)) { - return !options.constantGreaterThanVariable ? Ordering::greater : Ordering::less; + return !options.termOrderInversed ? Ordering::greater : Ordering::less; } if (!is(lhs) && is(rhs)) { - return options.constantGreaterThanVariable ? Ordering::greater : Ordering::less; + return options.termOrderInversed ? Ordering::greater : Ordering::less; } if (is(lhs) && !is(rhs)) { - return !options.constantGreaterThanVariable ? Ordering::greater : Ordering::less; + return !options.termOrderInversed ? Ordering::greater : Ordering::less; } if (!is(lhs) && is(rhs)) { - return options.constantGreaterThanVariable ? Ordering::greater : Ordering::less; + return options.termOrderInversed ? Ordering::greater : Ordering::less; } if (*lhs == *rhs) { @@ -235,10 +218,7 @@ Ordering compareNonExpressions(const ArgumentPtr &lhs, return lhs->toString() < rhs->toString() ? Ordering::greater : Ordering::less; } -Ordering comparePolynoms(const std::shared_ptr &lhs, - const std::shared_ptr &rhs, - const ComparatorOptions &options) { - +Ordering comparePolynoms(const PolynomPtr &lhs, const PolynomPtr &rhs, const ComparatorOptions &options) { const ChildrenComparatorResult childrenComp = compareChildren(lhs->getChildren(), rhs->getChildren(), options); if (childrenComp.postfix != Ordering::equal) { @@ -254,22 +234,12 @@ Ordering comparePolynoms(const std::shared_ptr &lhs, return childrenComp.prefixFirst; } - return compareFunctions(lhs->getFunction(), rhs->getFunction(), options); + return compareFunctions(lhs->getFunction(), rhs->getFunction()); } -Ordering compareExpressions(const std::shared_ptr &lhs, - const std::shared_ptr &rhs, - const ComparatorOptions &options) { - - const auto lhsOper = cast(lhs->getFunction()); - const auto rhsOper = cast(rhs->getFunction()); - - if ((lhsOper != nullptr) != (rhsOper != nullptr)) { - return compareFunctions(lhs->getFunction(), rhs->getFunction(), options); - } - +Ordering compareExpressions(const ExpressionPtr &lhs, const ExpressionPtr &rhs, const ComparatorOptions &options) { ComparatorOptions childCompOptions = options; - childCompOptions.constantGreaterThanVariable = false; + childCompOptions.termOrderInversed = false; const ChildrenComparatorResult childrenComp = compareChildren(lhs->getChildren(), rhs->getChildren(), childCompOptions); if (childrenComp.prefixVariables != Ordering::equal) { @@ -284,25 +254,17 @@ Ordering compareExpressions(const std::shared_ptr &lhs, if (childrenComp.postfix != Ordering::equal) { return childrenComp.postfix; } - - if (is(lhs->getFunction()) && is(rhs->getFunction())) { - if (childrenComp.prefixLast != Ordering::equal) { - return childrenComp.prefixLast; - } + if (childrenComp.prefixFirst != Ordering::equal) { + return childrenComp.prefixFirst; } - else { - if (childrenComp.prefixFirst != Ordering::equal) { - return childrenComp.prefixFirst; - } + if (childrenComp.prefixLast != Ordering::equal) { + return childrenComp.prefixLast; } - return compareFunctions(lhs->getFunction(), rhs->getFunction(), options); + return compareFunctions(lhs->getFunction(), rhs->getFunction()); } -Ordering comparePolynomAndNonPolynom(const std::shared_ptr &lhs, - const ArgumentPtr &rhs, - const ComparatorOptions &options) { - +Ordering comparePolynomAndNonPolynom(const PolynomPtr &lhs, const ArgumentPtr &rhs, const ComparatorOptions &options) { const ChildrenComparatorResult childrenComp = compareChildren(lhs->getChildren(), {rhs}, options); if (childrenComp.postfix != Ordering::equal) { @@ -312,62 +274,23 @@ Ordering comparePolynomAndNonPolynom(const std::shared_ptr &lhs, - const ArgumentPtr &rhs, - const ComparatorOptions &options) { - +Ordering compareExpressionAndNonExpression(const ExpressionPtr &lhs, const ArgumentPtr &rhs, const ComparatorOptions &options) { if (!is(rhs)) { - return !options.constantGreaterThanVariable ? Ordering::greater : Ordering::less; + return !options.termOrderInversed ? Ordering::greater : Ordering::less; } if (const auto res = compareTerms(lhs, rhs, options); res != Ordering::equal) { return res; } - if (!is(lhs->getFunction())) { - return !options.constantGreaterThanVariable ? Ordering::greater : Ordering::less; - } - if (const auto res = compareTerms(lhs, rhs, options); res != Ordering::equal) { return res; } - if (const auto lhsOper = cast(lhs->getFunction())) { - switch (lhsOper->getPriority()) { - case IOperator::Priority::PostfixUnary: - case IOperator::Priority::PrefixUnary: { - if (const Ordering res = compare(lhs->getChildren().front(), rhs); res != Ordering::equal) { - return res; - } - - return Ordering::less; - } - case IOperator::Priority::Exponentiation: - case IOperator::Priority::Multiplication: { - const ArgumentPtr rhsExpr = makeExpr(*lhsOper, rhs, Integer(1).clone()); - const Ordering res = compare(lhs, rhsExpr); - return options.constantGreaterThanVariable ? reverse(res) : res; - } - default: { - break; - } - } - } - - return !options.constantGreaterThanVariable ? Ordering::greater : Ordering::less; + return !options.termOrderInversed ? Ordering::greater : Ordering::less; } -Ordering compareFunctions(const std::shared_ptr &lhs, - const std::shared_ptr &rhs, - const ComparatorOptions &options) { - - if (is(lhs) && !is(rhs)) { - return options.constantGreaterThanVariable ? Ordering::greater : Ordering::less; - } - if (!is(lhs) && is(rhs)) { - return !options.constantGreaterThanVariable ? Ordering::greater : Ordering::less; - } - +Ordering compareFunctions(const std::shared_ptr &lhs, const std::shared_ptr &rhs) { if (*lhs == *rhs) { return Ordering::equal; } @@ -379,10 +302,7 @@ Ordering compareFunctions(const std::shared_ptr &lhs, return lhs->toString() < rhs->toString() ? Ordering::greater : Ordering::less; } -ChildrenComparatorResult compareChildren(const ArgumentPtrVector &lhsChildren, - const ArgumentPtrVector &rhsChildren, - const ComparatorOptions &options) { - +ChildrenComparatorResult compareChildren(const ArgumentPtrVector &lhsChildren, const ArgumentPtrVector &rhsChildren, const ComparatorOptions &options) { ChildrenComparatorResult result = {}; const size_t lhsStart = getPositionOfFirstChildWithTerm(lhsChildren); @@ -462,8 +382,8 @@ ChildrenComparatorResult compareChildren(const ArgumentPtrVector &lhsChildren, bool unwrapUnaryExpression(ArgumentPtr &arg) { if (const auto expr = cast(arg); - expr && - expr->getFunction()->getArgumentTypes().size() == 1) { + expr && + expr->getFunction()->getArgumentTypes().size() == 1) { arg = expr->getChildren().front(); return true; @@ -474,8 +394,8 @@ bool unwrapUnaryExpression(ArgumentPtr &arg) { bool unwrapEmptyExpression(ArgumentPtr &arg) { if (const auto expr = cast(arg); - expr && - !expr->getFunction()) { + expr && + !expr->getFunction()) { arg = expr->getChildren().front(); return true; @@ -488,4 +408,4 @@ Ordering reverse(const Ordering ordering) { return 0 <=> ordering; } -} +} \ No newline at end of file diff --git a/src/fintamath/expressions/ExpressionUtils.cpp b/src/fintamath/expressions/ExpressionUtils.cpp index ffe214ba4..6013facee 100644 --- a/src/fintamath/expressions/ExpressionUtils.cpp +++ b/src/fintamath/expressions/ExpressionUtils.cpp @@ -17,8 +17,10 @@ #include "fintamath/functions/IFunction.hpp" #include "fintamath/functions/IOperator.hpp" #include "fintamath/functions/arithmetic/Add.hpp" +#include "fintamath/functions/arithmetic/AddOper.hpp" #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" +#include "fintamath/functions/arithmetic/MulOper.hpp" #include "fintamath/functions/arithmetic/Neg.hpp" #include "fintamath/functions/powers/Pow.hpp" #include "fintamath/literals/Variable.hpp" @@ -254,6 +256,22 @@ ArgumentPtr negate(const ArgumentPtr &arg) { return mulExpr(Integer(-1).clone(), arg); } +ArgumentPtr invert(const ArgumentPtr &arg) { + if (const auto num = cast(arg)) { + return Integer(1) / (*num); + } + + if (const auto expr = cast(arg); expr && is
(expr->getFunction())) { + if (*expr->getChildren().front() == Integer(1)) { + return expr->getChildren().back(); + } + + return divExpr(expr->getChildren().back(), expr->getChildren().front()); + } + + return divExpr(Integer(1).clone(), arg); +} + ArgumentPtr makePolynom(const IFunction &func, ArgumentPtrVector &&args) { if (args.empty()) { return {}; @@ -329,14 +347,14 @@ std::string operatorChildToString(const IOperator &oper, const ArgumentPtr &chil } else if (const auto childComplex = cast(child)) { if (childComplex->real() != Integer(0)) { - childOper = std::make_shared(); + childOper = std::make_shared(); } else if (childComplex->imag() != Integer(1)) { if (childComplex->imag() == Integer(-1)) { childOper = std::make_shared(); } else { - childOper = std::make_shared(); + childOper = std::make_shared(); } } } @@ -348,7 +366,7 @@ std::string operatorChildToString(const IOperator &oper, const ArgumentPtr &chil } else if (is(child)) { if (childStr.find(Mul{}.toString()) != std::string::npos) { - childOper = std::make_shared(); + childOper = std::make_shared(); } } diff --git a/src/fintamath/expressions/FunctionExpression.cpp b/src/fintamath/expressions/FunctionExpression.cpp index 3cd53e225..861a46200 100644 --- a/src/fintamath/expressions/FunctionExpression.cpp +++ b/src/fintamath/expressions/FunctionExpression.cpp @@ -47,21 +47,25 @@ const ArgumentPtrVector &FunctionExpression::getChildren() const { } ArgumentPtr FunctionExpression::preSimplify() const { - auto simpl = cast(clone()); - - for (auto &child : simpl->children) { - preSimplifyChild(child); - } - - return simpl; + return simplifyRec(false); } ArgumentPtr FunctionExpression::postSimplify() const { + return simplifyRec(true); +} + +ArgumentPtr FunctionExpression::simplifyRec(bool isPostSimplify) const { auto simpl = cast(clone()); ArgumentRefVector args; for (auto &child : simpl->children) { - postSimplifyChild(child); + if (isPostSimplify) { + postSimplifyChild(child); + } + else { + preSimplifyChild(child); + } + args.emplace_back(*child); } @@ -79,4 +83,5 @@ void FunctionExpression::setChildren(const ArgumentPtrVector &childVect) { children = childVect; } + } diff --git a/src/fintamath/expressions/FunctionExpression.hpp b/src/fintamath/expressions/FunctionExpression.hpp index 54c5ffe7e..2f68c4f87 100644 --- a/src/fintamath/expressions/FunctionExpression.hpp +++ b/src/fintamath/expressions/FunctionExpression.hpp @@ -31,6 +31,9 @@ class FunctionExpression final : public IExpressionCRTP { ArgumentPtr postSimplify() const override; +private: + ArgumentPtr simplifyRec(bool isPostSimplify) const; + private: std::shared_ptr func; diff --git a/src/fintamath/expressions/binary/PowExpr.cpp b/src/fintamath/expressions/binary/PowExpr.cpp index 32a2d7e99..2fcf997d3 100644 --- a/src/fintamath/expressions/binary/PowExpr.cpp +++ b/src/fintamath/expressions/binary/PowExpr.cpp @@ -21,6 +21,7 @@ #include "fintamath/functions/arithmetic/Neg.hpp" #include "fintamath/functions/comparison/MoreEqv.hpp" #include "fintamath/functions/powers/Pow.hpp" +#include "fintamath/functions/powers/PowOper.hpp" #include "fintamath/functions/powers/Root.hpp" #include "fintamath/functions/powers/Sqrt.hpp" #include "fintamath/literals/Boolean.hpp" @@ -43,32 +44,8 @@ PowExpr::PowExpr(ArgumentPtr inLhsChild, ArgumentPtr inRhsChild) : IBinaryExpressionCRTP(Pow{}, std::move(inLhsChild), std::move(inRhsChild)) { } -std::string PowExpr::toString() const { - if (const auto rhsChildRat = cast(rhsChild)) { - const Integer &numerator = rhsChildRat->numerator(); - const Integer &denominator = rhsChildRat->denominator(); - - if (numerator == 1) { - if (denominator == 2) { - return functionToString(Sqrt{}, {lhsChild}); - } - - return functionToString(Root{}, {lhsChild, denominator.clone()}); - } - } - - if (const auto rhsChildExpr = cast(rhsChild); - rhsChildExpr && is
(rhsChildExpr->getFunction())) { - - if (*rhsChildExpr->getChildren().front() == Integer(1)) { - return functionToString(Root{}, {lhsChild, rhsChildExpr->getChildren().back()}); - } - } - - return IBinaryExpression::toString(); -} - const std::shared_ptr &PowExpr::getOutputFunction() const { + static const std::shared_ptr pow = std::make_shared(); static const std::shared_ptr sqrt = std::make_shared(); static const std::shared_ptr root = std::make_shared(); @@ -93,7 +70,21 @@ const std::shared_ptr &PowExpr::getOutputFunction() const { return root; } - return IBinaryExpression::getFunction(); + return pow; +} + +std::string PowExpr::toString() const { + const auto outFunc = getOutputFunction(); + + if (is(outFunc)) { + return functionToString(Sqrt{}, {lhsChild}); + } + + if (is(outFunc)) { + return functionToString(Root{}, {lhsChild, invert(rhsChild)}); + } + + return IBinaryExpression::toString(); } ArgumentPtr PowExpr::approximateSimplify() const { diff --git a/src/fintamath/expressions/binary/PowExpr.hpp b/src/fintamath/expressions/binary/PowExpr.hpp index 922782cb5..e97a19a16 100644 --- a/src/fintamath/expressions/binary/PowExpr.hpp +++ b/src/fintamath/expressions/binary/PowExpr.hpp @@ -16,10 +16,10 @@ class PowExpr final : public IBinaryExpressionCRTP { public: explicit PowExpr(ArgumentPtr inLhsChild, ArgumentPtr inRhsChild); - std::string toString() const override; - const std::shared_ptr &getOutputFunction() const override; + std::string toString() const override; + static constexpr MathObjectType getTypeStatic() { return {MathObjectType::PowExpr, "PowExpr"}; } diff --git a/src/fintamath/expressions/interfaces/IBinaryExpression.cpp b/src/fintamath/expressions/interfaces/IBinaryExpression.cpp index 5aa3be82a..a437570c8 100644 --- a/src/fintamath/expressions/interfaces/IBinaryExpression.cpp +++ b/src/fintamath/expressions/interfaces/IBinaryExpression.cpp @@ -21,11 +21,14 @@ IBinaryExpression::IBinaryExpression(const IFunction &inFunc, ArgumentPtr lhs, A } std::string IBinaryExpression::toString() const { - if (const auto oper = cast(func)) { - return binaryOperatorToString(*oper, lhsChild, rhsChild); + const auto &outFunc = getOutputFunction(); + const auto outOper = cast(outFunc); + + if (!outOper) { + return functionToString(*outFunc, {lhsChild, rhsChild}); } - return functionToString(*func, {lhsChild, rhsChild}); + return binaryOperatorToString(*outOper, lhsChild, rhsChild); } const std::shared_ptr &IBinaryExpression::getFunction() const { diff --git a/src/fintamath/expressions/interfaces/IPolynomExpression.cpp b/src/fintamath/expressions/interfaces/IPolynomExpression.cpp index e819a0624..79646bc4b 100644 --- a/src/fintamath/expressions/interfaces/IPolynomExpression.cpp +++ b/src/fintamath/expressions/interfaces/IPolynomExpression.cpp @@ -18,6 +18,7 @@ #include "fintamath/functions/IFunction.hpp" #include "fintamath/functions/IOperator.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" +#include "fintamath/functions/arithmetic/MulOper.hpp" namespace fintamath { @@ -37,20 +38,20 @@ const ArgumentPtrVector &IPolynomExpression::getChildren() const { } std::string IPolynomExpression::toString() const { - const auto oper = cast(func); - if (!oper) { - return functionToString(*func, children); - } + const auto &outFunc = getOutputFunction(); + const auto outOper = cast(outFunc); - std::string result; + if (!outOper) { + return functionToString(*outFunc, children); + } - result += childToString(*oper, children.front(), {}); + std::string result = childToString(*outOper, children.front(), {}); for (const auto i : stdv::iota(1U, children.size())) { - const std::string childStr = childToString(*oper, children[i], children[i - 1]); + const std::string childStr = childToString(*outOper, children[i], children[i - 1]); if (childStr.size() > 2 && childStr[0] == ' ' && std::isdigit(childStr[1]) && std::isdigit(result.back())) { - result += Mul{}.toString() + childStr.substr(1); + result += MulOper{}.toString() + childStr.substr(1); } else { result += childStr; @@ -195,12 +196,13 @@ IPolynomExpression::SimplifyFunctionVector IPolynomExpression::getFunctionsForPo std::string IPolynomExpression::childToString(const IOperator &oper, const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const { const std::string childStr = operatorChildToString(oper, inChild); - return prevChild ? (putInSpaces(func->toString()) + childStr) : childStr; + const std::string operStr = prevChild ? putInSpaces(oper.toString()) : ""; + return operStr + childStr; } std::strong_ordering IPolynomExpression::compare(const ArgumentPtr &lhs, const ArgumentPtr &rhs) const { const ComparatorOptions options = { - .constantGreaterThanVariable = isConstantGreaterThanVariable(), + .termOrderInversed = isConstantGreaterThanVariable(), .comparableOrderInversed = isComparableOrderInversed(), }; return fintamath::compare(lhs, rhs, options); diff --git a/src/fintamath/expressions/interfaces/IUnaryExpression.cpp b/src/fintamath/expressions/interfaces/IUnaryExpression.cpp index ffbf50912..cbd844905 100644 --- a/src/fintamath/expressions/interfaces/IUnaryExpression.cpp +++ b/src/fintamath/expressions/interfaces/IUnaryExpression.cpp @@ -20,15 +20,18 @@ IUnaryExpression::IUnaryExpression(const IFunction &inFunc, ArgumentPtr rhs) } std::string IUnaryExpression::toString() const { - if (const auto oper = cast(func)) { - if (oper->getPriority() == IOperator::Priority::PostfixUnary) { - return detail::postfixUnaryOperatorToString(*oper, child); - } + const auto &outFunc = getOutputFunction(); + const auto outOper = cast(outFunc); + + if (!outOper) { + return functionToString(*outFunc, {child}); + } - return detail::prefixUnaryOperatorToString(*oper, child); + if (outOper->getPriority() == IOperator::Priority::PostfixUnary) { + return postfixUnaryOperatorToString(*outOper, child); } - return detail::functionToString(*func, {child}); + return prefixUnaryOperatorToString(*outOper, child); } const std::shared_ptr &IUnaryExpression::getFunction() const { diff --git a/src/fintamath/expressions/polynomial/AddExpr.cpp b/src/fintamath/expressions/polynomial/AddExpr.cpp index 82630599d..946d8fa50 100644 --- a/src/fintamath/expressions/polynomial/AddExpr.cpp +++ b/src/fintamath/expressions/polynomial/AddExpr.cpp @@ -16,6 +16,7 @@ #include "fintamath/functions/IFunction.hpp" #include "fintamath/functions/IOperator.hpp" #include "fintamath/functions/arithmetic/Add.hpp" +#include "fintamath/functions/arithmetic/AddOper.hpp" #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" #include "fintamath/functions/arithmetic/Neg.hpp" @@ -39,6 +40,11 @@ AddExpr::AddExpr(ArgumentPtrVector inChildren) : IPolynomExpressionCRTP(Add{}, std::move(inChildren)) { } +const std::shared_ptr &AddExpr::getOutputFunction() const { + static const std::shared_ptr oper = std::make_shared(); + return oper; +} + std::string AddExpr::childToString(const IOperator &oper, const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const { std::string result = operatorChildToString(oper, inChild); bool isChildNegated = false; @@ -53,7 +59,7 @@ std::string AddExpr::childToString(const IOperator &oper, const ArgumentPtr &inC std::string funcStr; if (isChildNegated) { - funcStr = Sub{}.toString(); + funcStr = Neg{}.toString(); } else if (prevChild) { funcStr = oper.toString(); diff --git a/src/fintamath/expressions/polynomial/AddExpr.hpp b/src/fintamath/expressions/polynomial/AddExpr.hpp index 1e1403633..829d058e9 100644 --- a/src/fintamath/expressions/polynomial/AddExpr.hpp +++ b/src/fintamath/expressions/polynomial/AddExpr.hpp @@ -18,6 +18,8 @@ class AddExpr final : public IPolynomExpressionCRTP { public: explicit AddExpr(ArgumentPtrVector inChildren); + const std::shared_ptr &getOutputFunction() const override; + static constexpr MathObjectType getTypeStatic() { return {MathObjectType::AddExpr, "AddExpr"}; } diff --git a/src/fintamath/expressions/polynomial/AndExpr.cpp b/src/fintamath/expressions/polynomial/AndExpr.cpp index 4f707493b..d0d843833 100644 --- a/src/fintamath/expressions/polynomial/AndExpr.cpp +++ b/src/fintamath/expressions/polynomial/AndExpr.cpp @@ -8,6 +8,7 @@ #include "fintamath/functions/FunctionArguments.hpp" #include "fintamath/functions/IFunction.hpp" #include "fintamath/functions/logic/And.hpp" +#include "fintamath/functions/logic/AndOper.hpp" #include "fintamath/functions/logic/Not.hpp" #include "fintamath/functions/logic/Or.hpp" #include "fintamath/literals/Boolean.hpp" @@ -18,6 +19,11 @@ AndExpr::AndExpr(ArgumentPtrVector inChildren) : IPolynomExpressionCRTP(And{}, std::move(inChildren)) { } +const std::shared_ptr &AndExpr::getOutputFunction() const { + static const std::shared_ptr oper = std::make_shared(); + return oper; +} + AndExpr::SimplifyFunctionVector AndExpr::getFunctionsForPreSimplify() const { static const SimplifyFunctionVector simplifyFunctions = { &AndExpr::boolSimplify, diff --git a/src/fintamath/expressions/polynomial/AndExpr.hpp b/src/fintamath/expressions/polynomial/AndExpr.hpp index e60e8e1ea..08105b9d4 100644 --- a/src/fintamath/expressions/polynomial/AndExpr.hpp +++ b/src/fintamath/expressions/polynomial/AndExpr.hpp @@ -11,6 +11,8 @@ class AndExpr final : public IPolynomExpressionCRTP { public: explicit AndExpr(ArgumentPtrVector inChildren); + const std::shared_ptr &getOutputFunction() const override; + static constexpr MathObjectType getTypeStatic() { return {MathObjectType::AndExpr, "AndExpr"}; } diff --git a/src/fintamath/expressions/polynomial/MulExpr.cpp b/src/fintamath/expressions/polynomial/MulExpr.cpp index 0b9d3c399..ae27201dc 100644 --- a/src/fintamath/expressions/polynomial/MulExpr.cpp +++ b/src/fintamath/expressions/polynomial/MulExpr.cpp @@ -14,6 +14,7 @@ #include "fintamath/functions/arithmetic/Add.hpp" #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" +#include "fintamath/functions/arithmetic/MulOper.hpp" #include "fintamath/functions/arithmetic/Neg.hpp" #include "fintamath/functions/arithmetic/Sign.hpp" #include "fintamath/functions/logarithms/Log.hpp" @@ -35,6 +36,11 @@ MulExpr::MulExpr(ArgumentPtrVector inChildren) : IPolynomExpressionCRTP(Mul{}, std::move(inChildren)) { } +const std::shared_ptr &MulExpr::getOutputFunction() const { + static const std::shared_ptr oper = std::make_shared(); + return oper; +} + std::string MulExpr::toString() const { auto [childNumerator, childDenominator] = splitRational(children.front()); diff --git a/src/fintamath/expressions/polynomial/MulExpr.hpp b/src/fintamath/expressions/polynomial/MulExpr.hpp index b23503bb2..c59f44bff 100644 --- a/src/fintamath/expressions/polynomial/MulExpr.hpp +++ b/src/fintamath/expressions/polynomial/MulExpr.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include "fintamath/core/MathObjectType.hpp" @@ -14,6 +15,8 @@ class MulExpr final : public IPolynomExpressionCRTP { std::string toString() const override; + const std::shared_ptr &getOutputFunction() const override; + static constexpr MathObjectType getTypeStatic() { return {MathObjectType::MulExpr, "MulExpr"}; } diff --git a/src/fintamath/expressions/polynomial/OrExpr.cpp b/src/fintamath/expressions/polynomial/OrExpr.cpp index bf3ff4b2b..555d87252 100644 --- a/src/fintamath/expressions/polynomial/OrExpr.cpp +++ b/src/fintamath/expressions/polynomial/OrExpr.cpp @@ -14,6 +14,7 @@ #include "fintamath/functions/logic/And.hpp" #include "fintamath/functions/logic/Not.hpp" #include "fintamath/functions/logic/Or.hpp" +#include "fintamath/functions/logic/OrOper.hpp" #include "fintamath/literals/Boolean.hpp" namespace fintamath { @@ -24,6 +25,11 @@ OrExpr::OrExpr(ArgumentPtrVector inChildren) : IPolynomExpressionCRTP(Or{}, std::move(inChildren)) { } +const std::shared_ptr &OrExpr::getOutputFunction() const { + static const std::shared_ptr oper = std::make_shared(); + return oper; +} + std::string OrExpr::childToString(const IOperator &oper, const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const { std::string result = operatorChildToString(oper, inChild); diff --git a/src/fintamath/expressions/polynomial/OrExpr.hpp b/src/fintamath/expressions/polynomial/OrExpr.hpp index 15b0c06a0..c8da71bab 100644 --- a/src/fintamath/expressions/polynomial/OrExpr.hpp +++ b/src/fintamath/expressions/polynomial/OrExpr.hpp @@ -13,6 +13,8 @@ class OrExpr final : public IPolynomExpressionCRTP { public: explicit OrExpr(ArgumentPtrVector inChildren); + const std::shared_ptr &getOutputFunction() const override; + static constexpr MathObjectType getTypeStatic() { return {MathObjectType::OrExpr, "OrExpr"}; } diff --git a/src/fintamath/functions/arithmetic/AddOper.cpp b/src/fintamath/functions/arithmetic/AddOper.cpp new file mode 100644 index 000000000..92e639c88 --- /dev/null +++ b/src/fintamath/functions/arithmetic/AddOper.cpp @@ -0,0 +1,15 @@ +#include "fintamath/functions/arithmetic/AddOper.hpp" + +#include + +#include "fintamath/core/IMathObject.hpp" +#include "fintamath/functions/FunctionArguments.hpp" +#include "fintamath/functions/arithmetic/Add.hpp" + +namespace fintamath { + +std::unique_ptr AddOper::call(const ArgumentRefVector &argVect) const { + return Add{}(argVect); +} + +} diff --git a/src/fintamath/functions/arithmetic/MulOper.cpp b/src/fintamath/functions/arithmetic/MulOper.cpp new file mode 100644 index 000000000..251e9e449 --- /dev/null +++ b/src/fintamath/functions/arithmetic/MulOper.cpp @@ -0,0 +1,15 @@ +#include "fintamath/functions/arithmetic/MulOper.hpp" + +#include + +#include "fintamath/core/IMathObject.hpp" +#include "fintamath/functions/FunctionArguments.hpp" +#include "fintamath/functions/arithmetic/Mul.hpp" + +namespace fintamath { + +std::unique_ptr MulOper::call(const ArgumentRefVector &argVect) const { + return Mul{}(argVect); +} + +} diff --git a/src/fintamath/functions/logic/AndOper.cpp b/src/fintamath/functions/logic/AndOper.cpp new file mode 100644 index 000000000..a3672043d --- /dev/null +++ b/src/fintamath/functions/logic/AndOper.cpp @@ -0,0 +1,15 @@ +#include "fintamath/functions/logic/AndOper.hpp" + +#include + +#include "fintamath/core/IMathObject.hpp" +#include "fintamath/functions/FunctionArguments.hpp" +#include "fintamath/functions/logic/And.hpp" + +namespace fintamath { + +std::unique_ptr AndOper::call(const ArgumentRefVector &argVect) const { + return And{}(argVect); +} + +} diff --git a/src/fintamath/functions/logic/OrOper.cpp b/src/fintamath/functions/logic/OrOper.cpp new file mode 100644 index 000000000..df3f81766 --- /dev/null +++ b/src/fintamath/functions/logic/OrOper.cpp @@ -0,0 +1,15 @@ +#include "fintamath/functions/logic/OrOper.hpp" + +#include + +#include "fintamath/core/IMathObject.hpp" +#include "fintamath/functions/FunctionArguments.hpp" +#include "fintamath/functions/logic/Or.hpp" + +namespace fintamath { + +std::unique_ptr OrOper::call(const ArgumentRefVector &argVect) const { + return Or{}(argVect); +} + +} diff --git a/src/fintamath/functions/powers/PowFunction.cpp b/src/fintamath/functions/powers/PowOper.cpp similarity index 60% rename from src/fintamath/functions/powers/PowFunction.cpp rename to src/fintamath/functions/powers/PowOper.cpp index 2cb0dd7dc..89cab9859 100644 --- a/src/fintamath/functions/powers/PowFunction.cpp +++ b/src/fintamath/functions/powers/PowOper.cpp @@ -1,4 +1,4 @@ -#include "fintamath/functions/powers/PowFunction.hpp" +#include "fintamath/functions/powers/PowOper.hpp" #include @@ -8,7 +8,7 @@ namespace fintamath { -std::unique_ptr PowFunction::call(const ArgumentRefVector &argVect) const { +std::unique_ptr PowOper::call(const ArgumentRefVector &argVect) const { return Pow{}(argVect); } diff --git a/tests/src/core/ParseTests.cpp b/tests/src/core/ParseTests.cpp index b6effad91..2ce706c59 100644 --- a/tests/src/core/ParseTests.cpp +++ b/tests/src/core/ParseTests.cpp @@ -7,10 +7,12 @@ #include "fintamath/functions/IOperator.hpp" #include "fintamath/functions/arithmetic/Abs.hpp" #include "fintamath/functions/arithmetic/Add.hpp" +#include "fintamath/functions/arithmetic/AddOper.hpp" #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Frac.hpp" #include "fintamath/functions/arithmetic/FracMixed.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" +#include "fintamath/functions/arithmetic/MulOper.hpp" #include "fintamath/functions/arithmetic/Neg.hpp" #include "fintamath/functions/arithmetic/Sign.hpp" #include "fintamath/functions/arithmetic/Sub.hpp" @@ -40,11 +42,13 @@ #include "fintamath/functions/logarithms/Ln.hpp" #include "fintamath/functions/logarithms/Log.hpp" #include "fintamath/functions/logic/And.hpp" +#include "fintamath/functions/logic/AndOper.hpp" #include "fintamath/functions/logic/Equiv.hpp" #include "fintamath/functions/logic/Impl.hpp" #include "fintamath/functions/logic/Nequiv.hpp" #include "fintamath/functions/logic/Not.hpp" #include "fintamath/functions/logic/Or.hpp" +#include "fintamath/functions/logic/OrOper.hpp" #include "fintamath/functions/ntheory/Ceil.hpp" #include "fintamath/functions/ntheory/Floor.hpp" #include "fintamath/functions/other/Deg.hpp" @@ -53,7 +57,7 @@ #include "fintamath/functions/other/Percent.hpp" #include "fintamath/functions/powers/Exp.hpp" #include "fintamath/functions/powers/Pow.hpp" -#include "fintamath/functions/powers/PowFunction.hpp" +#include "fintamath/functions/powers/PowOper.hpp" #include "fintamath/functions/powers/Root.hpp" #include "fintamath/functions/powers/Sqrt.hpp" #include "fintamath/functions/trigonometry/Acos.hpp" @@ -208,6 +212,9 @@ TEST(ParseTests, parseConstantTest) { } TEST(ParseTests, parseFunctionTest) { + EXPECT_TRUE(is(IFunction::parse("add"))); + EXPECT_TRUE(is(IFunction::parse("mul"))); + EXPECT_TRUE(is(IFunction::parse("pow"))); EXPECT_TRUE(is(IFunction::parse("sqrt"))); EXPECT_TRUE(is(IFunction::parse("root"))); EXPECT_TRUE(is(IFunction::parse("exp"))); @@ -245,26 +252,27 @@ TEST(ParseTests, parseFunctionTest) { EXPECT_TRUE(is(IFunction::parse("integral"))); EXPECT_TRUE(is(IFunction::parse("frac", 2))); EXPECT_TRUE(is(IFunction::parse("frac", 3))); - EXPECT_TRUE(is(IFunction::parse("pow"))); EXPECT_TRUE(is(IFunction::parse("floor"))); EXPECT_TRUE(is(IFunction::parse("ceil"))); + EXPECT_TRUE(is(IFunction::parse("and"))); + EXPECT_TRUE(is(IFunction::parse("or"))); EXPECT_EQ(IFunction::parse("asdgewfe"), nullptr); EXPECT_EQ(IFunction::parse("1224"), nullptr); } TEST(ParseTests, parseOperatorTest) { - EXPECT_TRUE(is(IOperator::parse("+", IOperator::Priority::Addition))); + EXPECT_TRUE(is(IOperator::parse("+", IOperator::Priority::Addition))); EXPECT_TRUE(is(IOperator::parse("+", IOperator::Priority::PrefixUnary))); - EXPECT_TRUE(is(IOperator::parse("+", 2))); + EXPECT_TRUE(is(IOperator::parse("+", 2))); EXPECT_TRUE(is(IOperator::parse("+", 1))); EXPECT_TRUE(is(IOperator::parse("-", IOperator::Priority::Addition))); EXPECT_TRUE(is(IOperator::parse("-", IOperator::Priority::PrefixUnary))); EXPECT_TRUE(is(IOperator::parse("-", 2))); EXPECT_TRUE(is(IOperator::parse("-", 1))); - EXPECT_TRUE(is(IOperator::parse("*"))); + EXPECT_TRUE(is(IOperator::parse("*"))); EXPECT_TRUE(is
(IOperator::parse("/"))); - EXPECT_TRUE(is(IOperator::parse("^"))); + EXPECT_TRUE(is(IOperator::parse("^"))); EXPECT_TRUE(is(IOperator::parse("%"))); EXPECT_TRUE(is(IOperator::parse("!"))); EXPECT_TRUE(is(IOperator::parse("="))); @@ -274,8 +282,8 @@ TEST(ParseTests, parseOperatorTest) { EXPECT_TRUE(is(IOperator::parse("<="))); EXPECT_TRUE(is(IOperator::parse(">="))); EXPECT_TRUE(is(IOperator::parse("~"))); - EXPECT_TRUE(is(IOperator::parse("&"))); - EXPECT_TRUE(is(IOperator::parse("|"))); + EXPECT_TRUE(is(IOperator::parse("&"))); + EXPECT_TRUE(is(IOperator::parse("|"))); EXPECT_TRUE(is(IOperator::parse("->"))); EXPECT_TRUE(is(IOperator::parse("<->"))); EXPECT_TRUE(is(IOperator::parse("!<->"))); diff --git a/tests/src/expressions/interfaces/IBinaryExpressionTests.cpp b/tests/src/expressions/interfaces/IBinaryExpressionTests.cpp index 4b07788bd..56e6f722e 100644 --- a/tests/src/expressions/interfaces/IBinaryExpressionTests.cpp +++ b/tests/src/expressions/interfaces/IBinaryExpressionTests.cpp @@ -2,11 +2,11 @@ #include "fintamath/expressions/interfaces/IBinaryExpression.hpp" -#include "fintamath/functions/arithmetic/Add.hpp" +#include "fintamath/functions/arithmetic/AddOper.hpp" using namespace fintamath; -const Add f; +const AddOper f; namespace { diff --git a/tests/src/expressions/interfaces/IPolynomExpressionTests.cpp b/tests/src/expressions/interfaces/IPolynomExpressionTests.cpp index 0185cef2f..6512d3824 100644 --- a/tests/src/expressions/interfaces/IPolynomExpressionTests.cpp +++ b/tests/src/expressions/interfaces/IPolynomExpressionTests.cpp @@ -26,10 +26,10 @@ class TestPolynomExpression final : public IPolynomExpressionCRTPtoString(), "a * 2"); + EXPECT_EQ(expr.toMinimalObject()->toString(), "mul(a, 2)"); } TEST(IPolynomExpressionTests, getTypeTest) { EXPECT_EQ(IPolynomExpression::getTypeStatic(), MathObjectType(MathObjectType::IPolynomExpression, "IPolynomExpression")); -} +} \ No newline at end of file diff --git a/tests/src/functions/IOperatorTests.cpp b/tests/src/functions/IOperatorTests.cpp index 202cce0ae..e25bce79a 100644 --- a/tests/src/functions/IOperatorTests.cpp +++ b/tests/src/functions/IOperatorTests.cpp @@ -3,25 +3,26 @@ #include "fintamath/functions/IOperator.hpp" #include "fintamath/functions/arithmetic/Add.hpp" +#include "fintamath/functions/arithmetic/AddOper.hpp" #include "fintamath/functions/arithmetic/Neg.hpp" -#include "fintamath/functions/logic/Or.hpp" +#include "fintamath/functions/logic/OrOper.hpp" #include "fintamath/functions/other/Factorial.hpp" -#include "fintamath/functions/powers/Pow.hpp" +#include "fintamath/functions/powers/PowOper.hpp" using namespace fintamath; TEST(IOperatorTests, getPriorityTest) { - EXPECT_EQ(Add().getPriority(), IOperator::Priority::Addition); + EXPECT_EQ(AddOper().getPriority(), IOperator::Priority::Addition); EXPECT_EQ(Neg().getPriority(), IOperator::Priority::PrefixUnary); EXPECT_EQ(Factorial().getPriority(), IOperator::Priority::PostfixUnary); - EXPECT_EQ(Or().getPriority(), IOperator::Priority::Disjunction); + EXPECT_EQ(OrOper().getPriority(), IOperator::Priority::Disjunction); } TEST(IOperatorTests, isAssociativeTest) { - EXPECT_TRUE(Add().isAssociative()); + EXPECT_TRUE(AddOper().isAssociative()); EXPECT_FALSE(Neg().isAssociative()); - EXPECT_TRUE(Or().isAssociative()); - EXPECT_FALSE(Pow().isAssociative()); + EXPECT_TRUE(OrOper().isAssociative()); + EXPECT_FALSE(PowOper().isAssociative()); } TEST(IOperatorTests, getTypeTest) { diff --git a/tests/src/functions/arithmetic/AddOperTests.cpp b/tests/src/functions/arithmetic/AddOperTests.cpp new file mode 100644 index 000000000..a9e5839c3 --- /dev/null +++ b/tests/src/functions/arithmetic/AddOperTests.cpp @@ -0,0 +1,65 @@ +#include +#include + +#include "fintamath/functions/arithmetic/AddOper.hpp" + +#include "fintamath/exceptions/InvalidInputException.hpp" +#include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Rational.hpp" + +using namespace fintamath; + +using F = AddOper; +const F f; + +TEST(AddOperTests, toStringTest) { + EXPECT_EQ(f.toString(), "+"); +} + +TEST(AddOperTests, getArgumentTypesTest) { + EXPECT_THAT(f.getArgumentTypes(), testing::ElementsAre(IArithmetic::getTypeStatic(), IArithmetic::getTypeStatic())); +} + +TEST(AddOperTests, getReturnTypeTest) { + EXPECT_EQ(f.getReturnType(), IArithmetic::getTypeStatic()); +} + +TEST(AddOperTests, isVariadicTest) { + EXPECT_FALSE(F::isVariadicStatic()); + EXPECT_FALSE(f.isVariadic()); +} + +TEST(AddOperTests, isEvaluatableTest) { + EXPECT_TRUE(F::isEvaluatableStatic()); + EXPECT_TRUE(f.isEvaluatable()); +} + +TEST(AddOperTests, getPriorityTest) { + EXPECT_EQ(F::getPriorityStatic(), IOperator::Priority::Addition); + EXPECT_EQ(f.getPriority(), IOperator::Priority::Addition); +} + +TEST(AddOperTests, isAssociativeTest) { + EXPECT_TRUE(F::isAssociativeStatic()); + EXPECT_TRUE(f.isAssociative()); +} + +TEST(AddOperTests, callTest) { + EXPECT_EQ(f(Integer(3), Integer(5))->toString(), "8"); + EXPECT_EQ(f(Integer(3), Rational(5, 2))->toString(), "11/2"); + EXPECT_EQ(f(Rational(5, 2), Integer(3))->toString(), "11/2"); + EXPECT_EQ(f(Rational(5, 2), Rational(5, 2))->toString(), "5"); + EXPECT_EQ(f(Rational(5, 2), Rational(5, 3))->toString(), "25/6"); + + EXPECT_EQ(f(Integer(3), Variable("a"))->toString(), "a + 3"); + + EXPECT_THROW(f(Integer(1)), InvalidInputFunctionException); + EXPECT_THROW(f(Rational(2, 3)), InvalidInputFunctionException); + EXPECT_THROW(f(), InvalidInputFunctionException); + EXPECT_THROW(f(Integer(1), Integer(1), Integer(1)), InvalidInputFunctionException); +} + +TEST(AddOperTests, getTypeTest) { + EXPECT_EQ(F::getTypeStatic(), MathObjectType(MathObjectType::AddOper, "AddOper")); + EXPECT_EQ(f.getType(), MathObjectType(MathObjectType::AddOper, "AddOper")); +} diff --git a/tests/src/functions/arithmetic/AddTests.cpp b/tests/src/functions/arithmetic/AddTests.cpp index 2fe9654ea..a90d5527a 100644 --- a/tests/src/functions/arithmetic/AddTests.cpp +++ b/tests/src/functions/arithmetic/AddTests.cpp @@ -13,7 +13,7 @@ using F = Add; const F f; TEST(AddTests, toStringTest) { - EXPECT_EQ(f.toString(), "+"); + EXPECT_EQ(f.toString(), "add"); } TEST(AddTests, getArgumentTypesTest) { @@ -34,16 +34,6 @@ TEST(AddTests, isEvaluatableTest) { EXPECT_TRUE(f.isEvaluatable()); } -TEST(AddTests, getPriorityTest) { - EXPECT_EQ(F::getPriorityStatic(), IOperator::Priority::Addition); - EXPECT_EQ(f.getPriority(), IOperator::Priority::Addition); -} - -TEST(AddTests, isAssociativeTest) { - EXPECT_TRUE(F::isAssociativeStatic()); - EXPECT_TRUE(f.isAssociative()); -} - TEST(AddTests, callTest) { EXPECT_EQ(f(Integer(3), Integer(5))->toString(), "8"); EXPECT_EQ(f(Integer(3), Rational(5, 2))->toString(), "11/2"); diff --git a/tests/src/functions/arithmetic/MulOperTests.cpp b/tests/src/functions/arithmetic/MulOperTests.cpp new file mode 100644 index 000000000..4e1f91175 --- /dev/null +++ b/tests/src/functions/arithmetic/MulOperTests.cpp @@ -0,0 +1,63 @@ +#include +#include + +#include "fintamath/functions/arithmetic/MulOper.hpp" + +#include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Rational.hpp" + +using namespace fintamath; + +using F = MulOper; +const F f; + +TEST(MulOperTests, toStringTest) { + EXPECT_EQ(f.toString(), "*"); +} + +TEST(MulOperTests, getArgumentTypesTest) { + EXPECT_THAT(f.getArgumentTypes(), testing::ElementsAre(IArithmetic::getTypeStatic(), IArithmetic::getTypeStatic())); +} + +TEST(MulOperTests, getReturnTypeTest) { + EXPECT_EQ(f.getReturnType(), IArithmetic::getTypeStatic()); +} + +TEST(MulOperTests, isVariadicTest) { + EXPECT_FALSE(F::isVariadicStatic()); + EXPECT_FALSE(f.isVariadic()); +} + +TEST(MulOperTests, isEvaluatableTest) { + EXPECT_TRUE(F::isEvaluatableStatic()); + EXPECT_TRUE(f.isEvaluatable()); +} + +TEST(MulOperTests, getPriorityTest) { + EXPECT_EQ(F::getPriorityStatic(), IOperator::Priority::Multiplication); + EXPECT_EQ(f.getPriority(), IOperator::Priority::Multiplication); +} + +TEST(MulOperTests, isAssociativeTest) { + EXPECT_TRUE(F::isAssociativeStatic()); + EXPECT_TRUE(f.isAssociative()); +} + +TEST(MulOperTests, callTest) { + EXPECT_EQ(f(Integer(3), Integer(5))->toString(), "15"); + EXPECT_EQ(f(Integer(3), Rational(5, 2))->toString(), "15/2"); + EXPECT_EQ(f(Rational(5, 2), Integer(3))->toString(), "15/2"); + EXPECT_EQ(f(Rational(5, 2), Rational(5, 3))->toString(), "25/6"); + + EXPECT_EQ(f(Integer(3), Variable("a"))->toString(), "3 a"); + + EXPECT_THROW(f(Integer(1)), InvalidInputFunctionException); + EXPECT_THROW(f(Rational(2, 3)), InvalidInputFunctionException); + EXPECT_THROW(f(), InvalidInputFunctionException); + EXPECT_THROW(f(Integer(1), Integer(1), Integer(1)), InvalidInputFunctionException); +} + +TEST(MulOperTests, getTypeTest) { + EXPECT_EQ(F::getTypeStatic(), MathObjectType(MathObjectType::MulOper, "MulOper")); + EXPECT_EQ(f.getType(), MathObjectType(MathObjectType::MulOper, "MulOper")); +} diff --git a/tests/src/functions/arithmetic/MulTests.cpp b/tests/src/functions/arithmetic/MulTests.cpp index 6975d50f2..20f10dff6 100644 --- a/tests/src/functions/arithmetic/MulTests.cpp +++ b/tests/src/functions/arithmetic/MulTests.cpp @@ -12,7 +12,7 @@ using F = Mul; const F f; TEST(MulTests, toStringTest) { - EXPECT_EQ(f.toString(), "*"); + EXPECT_EQ(f.toString(), "mul"); } TEST(MulTests, getArgumentTypesTest) { @@ -33,16 +33,6 @@ TEST(MulTests, isEvaluatableTest) { EXPECT_TRUE(f.isEvaluatable()); } -TEST(MulTests, getPriorityTest) { - EXPECT_EQ(F::getPriorityStatic(), IOperator::Priority::Multiplication); - EXPECT_EQ(f.getPriority(), IOperator::Priority::Multiplication); -} - -TEST(MulTests, isAssociativeTest) { - EXPECT_TRUE(F::isAssociativeStatic()); - EXPECT_TRUE(f.isAssociative()); -} - TEST(MulTests, callTest) { EXPECT_EQ(f(Integer(3), Integer(5))->toString(), "15"); EXPECT_EQ(f(Integer(3), Rational(5, 2))->toString(), "15/2"); diff --git a/tests/src/functions/logic/AndOperTests.cpp b/tests/src/functions/logic/AndOperTests.cpp new file mode 100644 index 000000000..3c439cc0a --- /dev/null +++ b/tests/src/functions/logic/AndOperTests.cpp @@ -0,0 +1,62 @@ +#include +#include + +#include "fintamath/functions/logic/AndOper.hpp" + +#include "fintamath/literals/Boolean.hpp" +#include "fintamath/literals/Variable.hpp" + +using namespace fintamath; + +using F = AndOper; +const F f; + +TEST(AndOperTests, toStringTest) { + EXPECT_EQ(f.toString(), "&"); +} + +TEST(AndOperTests, getArgumentTypesTest) { + EXPECT_THAT(f.getArgumentTypes(), testing::ElementsAre(Boolean::getTypeStatic(), Boolean::getTypeStatic())); +} + +TEST(AndOperTests, getReturnTypeTest) { + EXPECT_EQ(f.getReturnType(), Boolean::getTypeStatic()); +} + +TEST(AndOperTests, isVariadicTest) { + EXPECT_FALSE(F::isVariadicStatic()); + EXPECT_FALSE(f.isVariadic()); +} + +TEST(AndOperTests, isEvaluatableTest) { + EXPECT_TRUE(F::isEvaluatableStatic()); + EXPECT_TRUE(f.isEvaluatable()); +} + +TEST(AndOperTests, getPriorityTest) { + EXPECT_EQ(F::getPriorityStatic(), IOperator::Priority::Conjunction); + EXPECT_EQ(f.getPriority(), IOperator::Priority::Conjunction); +} + +TEST(AndOperTests, isAssociativeTest) { + EXPECT_TRUE(F::isAssociativeStatic()); + EXPECT_TRUE(f.isAssociative()); +} + +TEST(AndOperTests, callTest) { + EXPECT_EQ(f(Boolean(false), Boolean(false))->toString(), "False"); + EXPECT_EQ(f(Boolean(false), Boolean(true))->toString(), "False"); + EXPECT_EQ(f(Boolean(true), Boolean(false))->toString(), "False"); + EXPECT_EQ(f(Boolean(true), Boolean(true))->toString(), "True"); + + EXPECT_EQ(f(Variable("a"), Variable("b"))->toString(), "a & b"); + + EXPECT_THROW(f(), InvalidInputFunctionException); + EXPECT_THROW(f(Boolean(true)), InvalidInputFunctionException); + EXPECT_THROW(f(Boolean(true), Boolean(true), Boolean(true)), InvalidInputFunctionException); +} + +TEST(AndOperTests, getTypeTest) { + EXPECT_EQ(F::getTypeStatic(), MathObjectType(MathObjectType::And, "And")); + EXPECT_EQ(f.getType(), MathObjectType(MathObjectType::And, "And")); +} diff --git a/tests/src/functions/logic/AndTests.cpp b/tests/src/functions/logic/AndTests.cpp index 523327cb8..00b76531c 100644 --- a/tests/src/functions/logic/AndTests.cpp +++ b/tests/src/functions/logic/AndTests.cpp @@ -12,7 +12,7 @@ using F = And; const F f; TEST(AndTests, toStringTest) { - EXPECT_EQ(f.toString(), "&"); + EXPECT_EQ(f.toString(), "and"); } TEST(AndTests, getArgumentTypesTest) { @@ -33,16 +33,6 @@ TEST(AndTests, isEvaluatableTest) { EXPECT_TRUE(f.isEvaluatable()); } -TEST(AndTests, getPriorityTest) { - EXPECT_EQ(F::getPriorityStatic(), IOperator::Priority::Conjunction); - EXPECT_EQ(f.getPriority(), IOperator::Priority::Conjunction); -} - -TEST(AndTests, isAssociativeTest) { - EXPECT_TRUE(F::isAssociativeStatic()); - EXPECT_TRUE(f.isAssociative()); -} - TEST(AndTests, callTest) { EXPECT_EQ(f(Boolean(false), Boolean(false))->toString(), "False"); EXPECT_EQ(f(Boolean(false), Boolean(true))->toString(), "False"); diff --git a/tests/src/functions/logic/OrOperTests.cpp b/tests/src/functions/logic/OrOperTests.cpp new file mode 100644 index 000000000..6daf584de --- /dev/null +++ b/tests/src/functions/logic/OrOperTests.cpp @@ -0,0 +1,62 @@ +#include +#include + +#include "fintamath/functions/logic/OrOper.hpp" + +#include "fintamath/literals/Boolean.hpp" +#include "fintamath/literals/Variable.hpp" + +using namespace fintamath; + +using F = OrOper; +const F f; + +TEST(OrOperTests, toStringTest) { + EXPECT_EQ(f.toString(), "|"); +} + +TEST(OrOperTests, getArgumentTypesTest) { + EXPECT_THAT(f.getArgumentTypes(), testing::ElementsAre(Boolean::getTypeStatic(), Boolean::getTypeStatic())); +} + +TEST(OrOperTests, getReturnTypeTest) { + EXPECT_EQ(f.getReturnType(), Boolean::getTypeStatic()); +} + +TEST(OrOperTests, isVariadicTest) { + EXPECT_FALSE(F::isVariadicStatic()); + EXPECT_FALSE(f.isVariadic()); +} + +TEST(OrOperTests, isEvaluatableTest) { + EXPECT_TRUE(F::isEvaluatableStatic()); + EXPECT_TRUE(f.isEvaluatable()); +} + +TEST(OrOperTests, getPriorityTest) { + EXPECT_EQ(F::getPriorityStatic(), IOperator::Priority::Disjunction); + EXPECT_EQ(f.getPriority(), IOperator::Priority::Disjunction); +} + +TEST(OrOperTests, isAssociativeTest) { + EXPECT_TRUE(F::isAssociativeStatic()); + EXPECT_TRUE(f.isAssociative()); +} + +TEST(OrOperTests, callTest) { + EXPECT_EQ(f(Boolean(false), Boolean(false))->toString(), "False"); + EXPECT_EQ(f(Boolean(false), Boolean(true))->toString(), "True"); + EXPECT_EQ(f(Boolean(true), Boolean(false))->toString(), "True"); + EXPECT_EQ(f(Boolean(true), Boolean(true))->toString(), "True"); + + EXPECT_EQ(f(Variable("a"), Variable("b"))->toString(), "a | b"); + + EXPECT_THROW(f(), InvalidInputFunctionException); + EXPECT_THROW(f(Boolean(true)), InvalidInputFunctionException); + EXPECT_THROW(f(Boolean(true), Boolean(true), Boolean(true)), InvalidInputFunctionException); +} + +TEST(OrOperTests, getTypeTest) { + EXPECT_EQ(F::getTypeStatic(), MathObjectType(MathObjectType::Or, "Or")); + EXPECT_EQ(f.getType(), MathObjectType(MathObjectType::Or, "Or")); +} diff --git a/tests/src/functions/logic/OrTests.cpp b/tests/src/functions/logic/OrTests.cpp index 647fe84dd..430a075cd 100644 --- a/tests/src/functions/logic/OrTests.cpp +++ b/tests/src/functions/logic/OrTests.cpp @@ -12,7 +12,7 @@ using F = Or; const F f; TEST(OrTests, toStringTest) { - EXPECT_EQ(f.toString(), "|"); + EXPECT_EQ(f.toString(), "or"); } TEST(OrTests, getArgumentTypesTest) { @@ -33,16 +33,6 @@ TEST(OrTests, isEvaluatableTest) { EXPECT_TRUE(f.isEvaluatable()); } -TEST(OrTests, getPriorityTest) { - EXPECT_EQ(F::getPriorityStatic(), IOperator::Priority::Disjunction); - EXPECT_EQ(f.getPriority(), IOperator::Priority::Disjunction); -} - -TEST(OrTests, isAssociativeTest) { - EXPECT_TRUE(F::isAssociativeStatic()); - EXPECT_TRUE(f.isAssociative()); -} - TEST(OrTests, callTest) { EXPECT_EQ(f(Boolean(false), Boolean(false))->toString(), "False"); EXPECT_EQ(f(Boolean(false), Boolean(true))->toString(), "True"); diff --git a/tests/src/functions/powers/PowFunctionTests.cpp b/tests/src/functions/powers/PowOperTests.cpp similarity index 51% rename from tests/src/functions/powers/PowFunctionTests.cpp rename to tests/src/functions/powers/PowOperTests.cpp index ecec32aaf..bd48eafd8 100644 --- a/tests/src/functions/powers/PowFunctionTests.cpp +++ b/tests/src/functions/powers/PowOperTests.cpp @@ -1,40 +1,51 @@ #include #include -#include "fintamath/functions/powers/PowFunction.hpp" +#include "fintamath/functions/powers/PowOper.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" using namespace fintamath; -using F = PowFunction; +using F = PowOper; const F f; -TEST(PowFunctionTests, toStringTest) { - EXPECT_EQ(f.toString(), "pow"); +TEST(PowOperTests, toStringTest) { + EXPECT_EQ(f.toString(), "^"); } -TEST(PowFunctionTests, getArgumentTypesTest) { +TEST(PowOperTests, getArgumentTypesTest) { EXPECT_THAT(f.getArgumentTypes(), testing::ElementsAre(IArithmetic::getTypeStatic(), IArithmetic::getTypeStatic())); } -TEST(PowFunctionTests, getReturnTypeTest) { +TEST(PowOperTests, getReturnTypeTest) { EXPECT_EQ(f.getReturnType(), IArithmetic::getTypeStatic()); } -TEST(PowFunctionTests, isVariadicTest) { +TEST(PowOperTests, isVariadicTest) { EXPECT_FALSE(F::isVariadicStatic()); EXPECT_FALSE(f.isVariadic()); } -TEST(PowFunctionTests, isEvaluatableTest) { +TEST(PowOperTests, isEvaluatableTest) { EXPECT_TRUE(F::isEvaluatableStatic()); EXPECT_TRUE(f.isEvaluatable()); } -TEST(PowFunctionTests, callTest) { +TEST(PowOperTests, getPriorityTest) { + EXPECT_EQ(F::getPriorityStatic(), IOperator::Priority::Exponentiation); + EXPECT_EQ(f.getPriority(), IOperator::Priority::Exponentiation); +} + +TEST(PowOperTests, isAssociativeTest) { + EXPECT_FALSE(F::isAssociativeStatic()); + EXPECT_FALSE(f.isAssociative()); +} + +TEST(PowOperTests, callTest) { EXPECT_EQ(f(Integer(3), Integer(2))->toString(), "9"); EXPECT_EQ(f(Rational(-10), Rational(-3))->toString(), "-1/1000"); @@ -42,13 +53,13 @@ TEST(PowFunctionTests, callTest) { EXPECT_EQ(f(Variable("a"), Rational(1, 2))->toString(), "sqrt(a)"); EXPECT_EQ(f(Variable("a"), Rational(3, 2))->toString(), "a^(3/2)"); - EXPECT_THROW(f(), InvalidInputFunctionException); - EXPECT_THROW(f(Integer(1)), InvalidInputFunctionException); - EXPECT_THROW(f(Rational(2, 3)), InvalidInputFunctionException); - EXPECT_THROW(f(Integer(1), Integer(1), Integer(1)), InvalidInputFunctionException); + EXPECT_THROW(f(), InvalidInputException); + EXPECT_THROW(f(Integer(1)), InvalidInputException); + EXPECT_THROW(f(Rational(2, 3)), InvalidInputException); + EXPECT_THROW(f(Integer(1), Integer(1), Integer(1)), InvalidInputException); } -TEST(PowFunctionTests, getTypeTest) { - EXPECT_EQ(F::getTypeStatic(), MathObjectType(MathObjectType::PowFunction, "PowFunction")); - EXPECT_EQ(f.getType(), MathObjectType(MathObjectType::PowFunction, "PowFunction")); +TEST(PowOperTests, getTypeTest) { + EXPECT_EQ(F::getTypeStatic(), MathObjectType(MathObjectType::PowOper, "PowOper")); + EXPECT_EQ(f.getType(), MathObjectType(MathObjectType::PowOper, "PowOper")); } diff --git a/tests/src/functions/powers/PowTests.cpp b/tests/src/functions/powers/PowTests.cpp index 5bf2b8653..a212e8751 100644 --- a/tests/src/functions/powers/PowTests.cpp +++ b/tests/src/functions/powers/PowTests.cpp @@ -14,7 +14,7 @@ using F = Pow; const F f; TEST(PowTests, toStringTest) { - EXPECT_EQ(f.toString(), "^"); + EXPECT_EQ(f.toString(), "pow"); } TEST(PowTests, getArgumentTypesTest) { @@ -35,16 +35,6 @@ TEST(PowTests, isEvaluatableTest) { EXPECT_TRUE(f.isEvaluatable()); } -TEST(PowTests, getPriorityTest) { - EXPECT_EQ(F::getPriorityStatic(), IOperator::Priority::Exponentiation); - EXPECT_EQ(f.getPriority(), IOperator::Priority::Exponentiation); -} - -TEST(PowTests, isAssociativeTest) { - EXPECT_FALSE(F::isAssociativeStatic()); - EXPECT_FALSE(f.isAssociative()); -} - TEST(PowTests, callTest) { EXPECT_EQ(f(Integer(3), Integer(0))->toString(), "1");