Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,26 @@ target_link_libraries(MyApp PRIVATE Oasis::Oasis)
```c++
#include <cstdlib>
#include <print> // C++23
#include <utility>
#include <memory>

#include <Oasis/Add.hpp>
#include <Oasis/Real.hpp>
#include <Oasis/SimplifyVisitor.hpp>

int main() {
SimplifyVisitor simplifyVisitor{};
Oasis::Add sum {
Oasis::Real{2.0},
Oasis::Real{3.0}
};

auto simplified = sum.Simplify();
auto expr = sum.Accept(simplifiedVisitor);
if (!expr) { // Error Case
std::println(expr.error());
return EXIT_FAILURE;
}
auto simplified = std::move(expr).value();
std::println("Result: {}", simplified->ToString());

return EXIT_SUCCESS;
Expand Down
2 changes: 2 additions & 0 deletions include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ set(Oasis_HEADERS
Oasis/Pi.hpp
Oasis/Real.hpp
Oasis/RecursiveCast.hpp
Oasis/SimplifyVisitor.hpp
Oasis/Sine.hpp
Oasis/Subtract.hpp
Oasis/UnaryExpression.hpp
Oasis/Undefined.hpp
Expand Down
2 changes: 1 addition & 1 deletion include/Oasis/Add.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Add<
public:
using BinaryExpression::BinaryExpression;

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;
[[deprecated]] [[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;

[[nodiscard]] auto Integrate(const Expression& integrationVariable) const -> std::unique_ptr<Expression> final;
[[nodiscard]] auto Differentiate(const Expression& differentiationVariable) const -> std::unique_ptr<Expression> final;
Expand Down
19 changes: 16 additions & 3 deletions include/Oasis/BinaryExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <list>

#include "Expression.hpp"
#include "Oasis/SimplifyVisitor.hpp"
#include "RecursiveCast.hpp"
#include "Visit.hpp"

Expand Down Expand Up @@ -199,7 +200,13 @@ class BinaryExpression : public Expression {

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> override
{
return Generalize()->Simplify();
SimplifyVisitor simplifyVisitor {};
auto e = Generalize();
auto s = e->Accept(simplifyVisitor);
if (!s) {
return e;
}
return std::move(s).value();
}

[[nodiscard]] auto Integrate(const Expression& integrationVariable) const -> std::unique_ptr<Expression> override
Expand Down Expand Up @@ -361,11 +368,17 @@ class BinaryExpression : public Expression {

auto Substitute(const Expression& var, const Expression& val) -> std::unique_ptr<Expression> override
{
// TODO: FIX WITH VISITOR?
std::unique_ptr<Expression> left = ((GetMostSigOp()).Copy())->Substitute(var, val);
std::unique_ptr<Expression> right = ((GetLeastSigOp().Copy())->Substitute(var, val));
DerivedT<Expression, Expression> comb = DerivedT<Expression, Expression> { *left, *right };
auto ret = comb.Simplify();
return ret;

Oasis::SimplifyVisitor simplifyVisitor {};
auto simplified = comb.Accept(simplifyVisitor);
if (!simplified) {
return comb.Generalize();
}
return std::move(simplified.value());
}
/**
* Swaps the operands of this expression.
Expand Down
2 changes: 1 addition & 1 deletion include/Oasis/Derivative.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Derivative<Expression, Expression> : public BinaryExpression<Derivative> {

Derivative(const Expression& Exp, const Expression& Var);

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;
[[deprecated]] [[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;

[[nodiscard]] auto Differentiate(const Expression& differentiationVariable) const -> std::unique_ptr<Expression> override;

Expand Down
2 changes: 1 addition & 1 deletion include/Oasis/Divide.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Divide<Expression, Expression> : public BinaryExpression<Divide> {

Divide(const Expression& dividend, const Expression& divisor);

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;
[[deprecated]] [[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;

[[nodiscard]] auto Differentiate(const Expression& differentiationVariable) const -> std::unique_ptr<Expression> final;

Expand Down
2 changes: 1 addition & 1 deletion include/Oasis/Exponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Exponent<Expression, Expression> : public BinaryExpression<Exponent> {

Exponent(const Expression& base, const Expression& power);

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;
[[deprecated]] [[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;

[[nodiscard]] auto Differentiate(const Expression& differentiationVariable) const -> std::unique_ptr<Expression> final;

Expand Down
5 changes: 3 additions & 2 deletions include/Oasis/Expression.hpp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the = 0 from the Simplify method so that it is no longer pure virtual (i.e abstract). The default implementation should call the new SimplifyVisitor. This is so that new Expression types don't have to implement the now deprecated Simplify.

Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ enum class ExpressionType {
Matrix,
Pi,
EulerNumber,
Magnitude
Magnitude,
Sine
};

/**
Expand Down Expand Up @@ -210,7 +211,7 @@ template <IVisitor T>
auto Expression::Accept(T& visitor) const -> typename T::RetT
{
try {
return boost::any_cast<typename T::RetT>(this->AcceptInternal(visitor));
return boost::any_cast<typename T::RetT>(this->AcceptInternal(static_cast<Visitor&>(visitor)));
} catch (boost::bad_any_cast& e) {
return std::unexpected { e.what() };
}
Expand Down
5 changes: 3 additions & 2 deletions include/Oasis/Integral.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ class Integral<Expression, Expression> : public BinaryExpression<Integral> {

Integral(const Expression& integrand, const Expression& differential);

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;
[[nodiscard]] auto Simplify(const Expression& upper, const Expression& lower) const -> std::unique_ptr<Expression> /* final */;
[[deprecated]] [[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;

[[deprecated]] [[nodiscard]] auto Simplify(const Expression& upper, const Expression& lower) const -> std::unique_ptr<Expression> /* final */;

EXPRESSION_TYPE(Integral)
EXPRESSION_CATEGORY(Associative | Commutative)
Expand Down
2 changes: 1 addition & 1 deletion include/Oasis/Log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Log<Expression, Expression> : public BinaryExpression<Log> {

Log(const Expression& base, const Expression& argument);

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;
[[deprecated]] [[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;

[[nodiscard]] auto Integrate(const Expression& integrationVariable) const -> std::unique_ptr<Expression> final;
[[nodiscard]] auto Differentiate(const Expression& differentiationVariable) const -> std::unique_ptr<Expression> final;
Expand Down
18 changes: 13 additions & 5 deletions include/Oasis/Magnitude.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Imaginary.hpp"
#include "Matrix.hpp"
#include "Multiply.hpp"
#include "Oasis/SimplifyVisitor.hpp"
#include "Real.hpp"
#include "RecursiveCast.hpp"
#include "UnaryExpression.hpp"
Expand All @@ -24,7 +25,7 @@ namespace Oasis {
* @tparam OperandT Type of child operand
* This represents magnitude/absolute value
*/
template <typename OperandT>
template <IExpression OperandT>
class Magnitude final : public UnaryExpression<Magnitude, OperandT> {
public:
Magnitude() = default;
Expand All @@ -38,8 +39,9 @@ class Magnitude final : public UnaryExpression<Magnitude, OperandT> {
{
}

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> override
[[deprecated]] [[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> override
{
SimplifyVisitor simplifyVisitor {};
auto simpOp = this->GetOperand().Simplify();
if (auto realCase = RecursiveCast<Real>(*simpOp); realCase != nullptr) {
double val = realCase->GetValue();
Expand All @@ -49,7 +51,12 @@ class Magnitude final : public UnaryExpression<Magnitude, OperandT> {
return std::make_unique<Real>(1.0);
}
if (auto mulImgCase = RecursiveCast<Multiply<Expression, Imaginary>>(*simpOp); mulImgCase != nullptr) {
return Magnitude<Expression> { mulImgCase->GetMostSigOp() }.Simplify();
auto e = Magnitude<Expression> { mulImgCase->GetMostSigOp() };
auto s = e.Accept(simplifyVisitor);
if (!s) {
return e.Generalize();
}
return std::move(s).value();
}
if (auto addCase = RecursiveCast<Add<Expression, Imaginary>>(*simpOp); addCase != nullptr) {
return Exponent { Add<Expression> { Exponent<Expression> { addCase->GetMostSigOp(), Real { 2 } },
Expand Down Expand Up @@ -79,12 +86,13 @@ class Magnitude final : public UnaryExpression<Magnitude, OperandT> {
[[nodiscard]] auto Differentiate(const Expression& var) const -> std::unique_ptr<Expression> override
{
// TODO: Implement
Oasis::SimplifyVisitor simplifyVisitor {};

const std::unique_ptr<Expression> operandDerivative = this->GetOperand().Differentiate(var);
return Magnitude<Expression> {
*operandDerivative
}
.Simplify();
.Generalize();
}

[[nodiscard]] auto Integrate(const Expression& integrationVar) const -> std::unique_ptr<Expression> override
Expand All @@ -94,7 +102,7 @@ class Magnitude final : public UnaryExpression<Magnitude, OperandT> {
return Magnitude<Expression> {
*operandDerivative
}
.Simplify();
.Generalize();
}

EXPRESSION_TYPE(Magnitude)
Expand Down
2 changes: 1 addition & 1 deletion include/Oasis/Multiply.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Multiply<Expression, Expression> : public BinaryExpression<Multiply> {
public:
using BinaryExpression::BinaryExpression;

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;
[[deprecated]] [[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;

[[nodiscard]] auto Differentiate(const Expression& differentiationVariable) const -> std::unique_ptr<Expression> final;

Expand Down
6 changes: 3 additions & 3 deletions include/Oasis/Negate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace Oasis {

template <typename OperandT = Expression>
template <IExpression OperandT = Expression>
class Negate final : public UnaryExpression<Negate, OperandT> {
public:
Negate() = default;
Expand All @@ -24,7 +24,7 @@ class Negate final : public UnaryExpression<Negate, OperandT> {
{
}

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> override
[[deprecated]] [[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> override
{
return Multiply {
Real { -1.0 },
Expand All @@ -39,7 +39,7 @@ class Negate final : public UnaryExpression<Negate, OperandT> {
return Negate<Expression> {
*operandDerivative
}
.Simplify();
.Generalize(); // TODO: FIX WITH VISITOR
}

EXPRESSION_TYPE(Negate)
Expand Down
57 changes: 57 additions & 0 deletions include/Oasis/SimplifyVisitor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// Created by Andrew Nazareth on 9/23/25.
//

#ifndef SIMPLIFYVISITOR_HPP
#define SIMPLIFYVISITOR_HPP

#include <format>
#include <string>

#include <gsl/gsl-lite.hpp>

#include "Oasis/Visit.hpp"

namespace Oasis {

struct SimplifyOpts {
enum class AngleUnits {
RADIANS,
DEGREES,
} angleUnits
= AngleUnits::RADIANS;
};

class SimplifyVisitor final : public TypedVisitor<std::expected<gsl::not_null<std::unique_ptr<Expression>>, std::string>> {
public:
SimplifyVisitor();
explicit SimplifyVisitor(SimplifyOpts& opts);

auto TypedVisit(const Real& real) -> RetT override;
auto TypedVisit(const Imaginary& imaginary) -> RetT override;
auto TypedVisit(const Variable& variable) -> RetT override;
auto TypedVisit(const Undefined& undefined) -> RetT override;
auto TypedVisit(const Add<Expression, Expression>& add) -> RetT override;
auto TypedVisit(const Subtract<Expression, Expression>& subtract) -> RetT override;
auto TypedVisit(const Multiply<Expression, Expression>& multiply) -> RetT override;
auto TypedVisit(const Divide<Expression, Expression>& divide) -> RetT override;
auto TypedVisit(const Exponent<Expression, Expression>& exponent) -> RetT override;
auto TypedVisit(const Log<Expression, Expression>& log) -> RetT override;
auto TypedVisit(const Negate<Expression>& negate) -> RetT override;
auto TypedVisit(const Sine<Expression>& sine) -> RetT override;
auto TypedVisit(const Derivative<Expression, Expression>& derivative) -> RetT override;
auto TypedVisit(const Integral<Expression, Expression>& integral) -> RetT override;
auto TypedVisit(const Matrix& matrix) -> RetT override;
auto TypedVisit(const EulerNumber&) -> RetT override;
auto TypedVisit(const Pi&) -> RetT override;
auto TypedVisit(const Magnitude<Expression>& magnitude) -> RetT override;

[[nodiscard]] SimplifyOpts GetOptions() const;

private:
SimplifyOpts options;
};

} // Oasis

#endif // SIMPLIFYVISITOR_HPP
41 changes: 41 additions & 0 deletions include/Oasis/Sine.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// Created by Andrew Nazareth on 9/19/25.
//

#ifndef OASIS_SINE_HPP
#define OASIS_SINE_HPP

#include "UnaryExpression.hpp"

namespace Oasis {

template <IExpression OperandT>
class Sine;

template <>
class Sine<Expression> final : public UnaryExpression<Sine> {
public:
Sine() = default;
Sine(const Sine& other)
: UnaryExpression<Sine>(other)
{
}

explicit Sine(const Expression& operand)
: UnaryExpression<Sine>(operand)
{
}

[[deprecated]] [[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> override;

[[nodiscard]] auto Differentiate(const Expression& var) const -> std::unique_ptr<Expression> override;

[[nodiscard]] auto Integrate(const Expression& var) const -> std::unique_ptr<Expression> override;

EXPRESSION_TYPE(Sine)
EXPRESSION_CATEGORY(UnExp)
};

} // Oasis

#endif // OASIS_SINE_HPP
2 changes: 1 addition & 1 deletion include/Oasis/Subtract.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Subtract<Expression, Expression> : public BinaryExpression<Subtract> {

Subtract(const Expression& minuend, const Expression& subtrahend);

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;
[[deprecated]] [[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;

[[nodiscard]] auto Differentiate(const Expression& differentiationVariable) const -> std::unique_ptr<Expression> final;

Expand Down
6 changes: 3 additions & 3 deletions include/Oasis/UnaryExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace Oasis {

template <template <IExpression> class DerivedT, IExpression OperandT>
template <template <IExpression> class DerivedT, IExpression OperandT = Expression>
class UnaryExpression : public Expression {

using DerivedSpecialized = DerivedT<OperandT>;
Expand Down Expand Up @@ -87,8 +87,8 @@ class UnaryExpression : public Expression {
{
std::unique_ptr<Expression> right = ((GetOperand().Copy())->Substitute(var, val));
DerivedT<Expression> comb = DerivedT<Expression> { *right };
auto ret = comb.Simplify();
return ret;
// auto ret = comb.Accept();
return comb.Generalize();
}

auto AcceptInternal(Visitor& visitor) const -> any override
Expand Down
Loading
Loading