Skip to content

Commit

Permalink
Merge pull request open-algebra#97 from ab235/feature-substitute
Browse files Browse the repository at this point in the history
Feature substitute
  • Loading branch information
ab235 authored Apr 16, 2024
2 parents 46142ac + 94b47a9 commit ba69817
Show file tree
Hide file tree
Showing 30 changed files with 716 additions and 27 deletions.
5 changes: 3 additions & 2 deletions include/Oasis/Add.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ class Add<
auto Simplify(tf::Subflow& subflow) const -> std::unique_ptr<Expression> final;

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

DECL_SPECIALIZE(Add)

EXPRESSION_TYPE(Add)
EXPRESSION_CATEGORY(Associative | Commutative)
EXPRESSION_CATEGORY(Associative | Commutative | BinExp)
};
/// @endcond

Expand Down Expand Up @@ -64,7 +65,7 @@ class Add : public BinaryExpression<Add, AugendT, AddendT> {
auto operator=(const Add& other) -> Add& = default;

EXPRESSION_TYPE(Add)
EXPRESSION_CATEGORY(Associative | Commutative)
EXPRESSION_CATEGORY(Associative | Commutative | BinExp)
};

} // namespace Oasis
Expand Down
15 changes: 12 additions & 3 deletions include/Oasis/BinaryExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ class BinaryExpression : public Expression {

return std::make_unique<DerivedSpecialized>(copy);
}

[[nodiscard]] auto Differentiate(const Expression& differentiationVariable) -> std::unique_ptr<Expression> override
{
return Generalize()->Differentiate(differentiationVariable);
}
[[nodiscard]] auto Equals(const Expression& other) const -> bool final
{
if (this->GetType() != other.GetType()) {
Expand Down Expand Up @@ -471,7 +474,14 @@ class BinaryExpression : public Expression {
this->leastSigOp = std::move(op);
}
}

auto Substitute(const Expression& var, const Expression& val) -> std::unique_ptr<Expression> override
{
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;
}
/**
* Swaps the operands of this expression.
* @return A new expression with the operands swapped.
Expand All @@ -494,7 +504,6 @@ class BinaryExpression : public Expression {
if (!other.Is<Oasis::Derived>()) { \
return nullptr; \
} \
\
auto specialized = std::make_unique<Derived<FirstOp, SecondOp>>(); \
\
std::unique_ptr<Expression> otherGeneralized = other.Generalize(); \
Expand Down
76 changes: 76 additions & 0 deletions include/Oasis/Derivative.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//
// Created by bachia on 4/12/2024.
//

#ifndef OASIS_DERIVATIVE_HPP
#define OASIS_DERIVATIVE_HPP

#include "fmt/core.h"

#include "BinaryExpression.hpp"
#include "Expression.hpp"
#include "Real.hpp"

namespace Oasis {

template <IExpression Exp, IExpression Var>
class Derivative;

/// @cond
template <>
class Derivative<Expression, Expression> : public BinaryExpression<Derivative> {
public:
Derivative() = default;
Derivative(const Derivative<Expression, Expression>& other) = default;

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

[[nodiscard]] auto Simplify() const -> std::unique_ptr<Expression> final;
// auto Simplify(tf::Subflow& subflow) const -> std::unique_ptr<Expression> final;

[[nodiscard]] auto ToString() const -> std::string final;

static auto Specialize(const Expression& other) -> std::unique_ptr<Derivative>;
static auto Specialize(const Expression& other, tf::Subflow& subflow) -> std::unique_ptr<Derivative>;

EXPRESSION_TYPE(Derivative)
EXPRESSION_CATEGORY(BinExp)
};
/// @endcond

/**
* The Derivative expression Derivatives the expression given
*
* @tparam Exp The expression to be Derived.
* @tparam Var The variable to be Derived on.
*/
template <IExpression Exp = Expression, IExpression Var = Exp>
class Derivative : public BinaryExpression<Derivative, Exp, Var> {
public:
Derivative() = default;
Derivative(const Derivative<Exp, Var>& other)
: BinaryExpression<Derivative, Exp, Var>(other)
{
}

Derivative(const Exp& exp, const Var& var)
: BinaryExpression<Derivative, Exp, Var>(exp, var)
{
}

[[nodiscard]] auto ToString() const -> std::string final
{
return fmt::format("(d/d{}({}))", this->leastSigOp->ToString(), this->mostSigOp->ToString());
}

IMPL_SPECIALIZE(Derivative, Exp, Var)

auto operator=(const Derivative& other) -> Derivative& = default;

EXPRESSION_TYPE(Derivative)
EXPRESSION_CATEGORY(BinExp)
};

} // namespace Oasis

#endif // OASIS_DERIVATIVE_HPP
5 changes: 3 additions & 2 deletions include/Oasis/Divide.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ class Divide<Expression, Expression> : public BinaryExpression<Divide> {
auto Simplify(tf::Subflow& subflow) const -> std::unique_ptr<Expression> final;

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

static auto Specialize(const Expression& other) -> std::unique_ptr<Divide>;
static auto Specialize(const Expression& other, tf::Subflow& subflow) -> std::unique_ptr<Divide>;

EXPRESSION_TYPE(Divide)
EXPRESSION_CATEGORY(Associative | Commutative)
EXPRESSION_CATEGORY(BinExp)
};
/// @endcond

Expand Down Expand Up @@ -67,7 +68,7 @@ class Divide : public BinaryExpression<Divide, DividendT, DivisorT> {
auto operator=(const Divide& other) -> Divide& = default;

EXPRESSION_TYPE(Divide)
EXPRESSION_CATEGORY(None)
EXPRESSION_CATEGORY(BinExp)
};

} // Oasis
Expand Down
5 changes: 3 additions & 2 deletions include/Oasis/Exponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ class Exponent<Expression, Expression> : public BinaryExpression<Exponent> {
auto Simplify(tf::Subflow& subflow) const -> std::unique_ptr<Expression> final;

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

static auto Specialize(const Expression& other) -> std::unique_ptr<Exponent>;
static auto Specialize(const Expression& other, tf::Subflow& subflow) -> std::unique_ptr<Exponent>;

EXPRESSION_TYPE(Exponent)
EXPRESSION_CATEGORY(0)
EXPRESSION_CATEGORY(BinExp)
};
/// @endcond

Expand Down Expand Up @@ -68,7 +69,7 @@ class Exponent : public BinaryExpression<Exponent, BaseT, PowerT> {
auto operator=(const Exponent& other) -> Exponent& = default;

EXPRESSION_TYPE(Exponent)
EXPRESSION_CATEGORY(0)
EXPRESSION_CATEGORY(BinExp)
};

}
Expand Down
11 changes: 11 additions & 0 deletions include/Oasis/Expression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ enum class ExpressionType {
Divide,
Exponent,
Log,
Limit,
Derivative,
Negate,
Sqrt,
};
Expand All @@ -39,6 +41,8 @@ enum ExpressionCategory : uint32_t {
None = 0,
Associative = 1,
Commutative = 1 << 1,
BinExp = 1 << 2,
UnExp = 1 << 3,
};

// clang-format off
Expand Down Expand Up @@ -85,6 +89,12 @@ class Expression {
*/
virtual auto Copy(tf::Subflow& subflow) const -> std::unique_ptr<Expression> = 0;

/**
* Tries to differentiate this function.
* @return the differentiated expression.
*/
[[nodiscard]] virtual auto Differentiate(const Expression&) -> std::unique_ptr<Expression>;

/**
* Compares this expression to another expression for equality.
*
Expand Down Expand Up @@ -250,6 +260,7 @@ class Expression {
* @return Whether the two expressions are structurally equivalent.
*/
[[nodiscard]] auto StructurallyEquivalentAsync(const Expression& other) const -> bool;
[[nodiscard]] virtual auto Substitute(const Expression& var, const Expression& val) -> std::unique_ptr<Expression> = 0;

/**
* Converts this expression to a string.
Expand Down
2 changes: 1 addition & 1 deletion include/Oasis/Imaginary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Imaginary : public LeafExpression<Imaginary> {
[[nodiscard]] auto Equals(const Expression& other) const -> bool final;

EXPRESSION_TYPE(Imaginary)
EXPRESSION_CATEGORY(0)
EXPRESSION_CATEGORY(UnExp)

[[nodiscard]] auto ToString() const -> std::string final;

Expand Down
8 changes: 8 additions & 0 deletions include/Oasis/LeafExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ class LeafExpression : public Expression {
{
return this->GetType() == other.GetType();
}
[[nodiscard]] auto Differentiate(const Expression& differentiationVariable) -> std::unique_ptr<Expression> override
{
return Generalize()->Differentiate(differentiationVariable);
}
auto Substitute(const Expression&, const Expression&) -> std::unique_ptr<Expression> override
{
return this->Copy();
}
};

} // Oasis
Expand Down
4 changes: 2 additions & 2 deletions include/Oasis/Log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Log<Expression, Expression> : public BinaryExpression<Log> {
static auto Specialize(const Expression& other, tf::Subflow& subflow) -> std::unique_ptr<Log>;

EXPRESSION_TYPE(Log)
EXPRESSION_CATEGORY(None)
EXPRESSION_CATEGORY(BinExp)
};
/// @endcond

Expand Down Expand Up @@ -67,7 +67,7 @@ class Log : public BinaryExpression<Log, BaseT, ArgumentT> {
auto operator=(const Log& other) -> Log& = default;

EXPRESSION_TYPE(Log);
EXPRESSION_CATEGORY(None);
EXPRESSION_CATEGORY(BinExp);
};

} // Oasis
Expand Down
5 changes: 3 additions & 2 deletions include/Oasis/Multiply.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ class Multiply<Expression, Expression> : public BinaryExpression<Multiply> {
auto Simplify(tf::Subflow& subflow) const -> std::unique_ptr<Expression> final;

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

static auto Specialize(const Expression& other) -> std::unique_ptr<Multiply>;
static auto Specialize(const Expression& other, tf::Subflow& subflow) -> std::unique_ptr<Multiply>;

EXPRESSION_TYPE(Multiply)
EXPRESSION_CATEGORY(Associative | Commutative)
EXPRESSION_CATEGORY(Associative | Commutative | BinExp)
};
/// @endcond

Expand Down Expand Up @@ -64,7 +65,7 @@ class Multiply : public BinaryExpression<Multiply, MultiplicandT, MultiplierT> {
auto operator=(const Multiply& other) -> Multiply& = default;

EXPRESSION_TYPE(Multiply)
EXPRESSION_CATEGORY(Associative | Commutative)
EXPRESSION_CATEGORY(Associative | Commutative | BinExp)
};

} // Oasis
Expand Down
2 changes: 1 addition & 1 deletion include/Oasis/Negate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class Negate final : public UnaryExpression<Negate, OperandT> {
IMPL_SPECIALIZE_UNARYEXPR(Negate, OperandT)

EXPRESSION_TYPE(Negate)
EXPRESSION_CATEGORY(None)
EXPRESSION_CATEGORY(UnExp)
};

} // Oasis
Expand Down
3 changes: 2 additions & 1 deletion include/Oasis/Real.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Real : public LeafExpression<Real> {
[[nodiscard]] auto Equals(const Expression& other) const -> bool final;

EXPRESSION_TYPE(Real)
EXPRESSION_CATEGORY(0)
EXPRESSION_CATEGORY(UnExp)

/**
* Gets the value of the real number.
Expand All @@ -34,6 +34,7 @@ class Real : public LeafExpression<Real> {

static auto Specialize(const Expression& other) -> std::unique_ptr<Real>;
static auto Specialize(const Expression& other, tf::Subflow& subflow) -> std::unique_ptr<Real>;
[[nodiscard]] auto Differentiate(const Expression&) -> std::unique_ptr<Expression> final;

auto operator=(const Real& other) -> Real& = default;

Expand Down
5 changes: 3 additions & 2 deletions include/Oasis/Subtract.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ class Subtract<Expression, Expression> : public BinaryExpression<Subtract> {
auto Simplify(tf::Subflow& subflow) const -> std::unique_ptr<Expression> final;

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

static auto Specialize(const Expression& other) -> std::unique_ptr<Subtract>;
static auto Specialize(const Expression& other, tf::Subflow& subflow) -> std::unique_ptr<Subtract>;

EXPRESSION_TYPE(Subtract)
EXPRESSION_CATEGORY(0)
EXPRESSION_CATEGORY(BinExp)
};
/// @endcond

Expand Down Expand Up @@ -67,7 +68,7 @@ class Subtract : public BinaryExpression<Subtract, MinuendT, SubtrahendT> {
auto operator=(const Subtract& other) -> Subtract& = default;

EXPRESSION_TYPE(Subtract)
EXPRESSION_CATEGORY(None)
EXPRESSION_CATEGORY(BinExp)
};

} // Oasis
Expand Down
8 changes: 8 additions & 0 deletions include/Oasis/UnaryExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ class UnaryExpression : public Expression {
}
}

auto Substitute(const Expression& var, const Expression& val) -> std::unique_ptr<Expression> override
{
std::unique_ptr<Expression> right = ((GetOperand().Copy())->Substitute(var, val));
DerivedT<Expression> comb = DerivedT<Expression> { *right };
auto ret = comb.Simplify();
return ret;
}

protected:
std::unique_ptr<OperandT> op;
};
Expand Down
2 changes: 1 addition & 1 deletion include/Oasis/Undefined.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Undefined : public LeafExpression<Undefined> {
[[nodiscard]] auto Equals(const Expression&) const -> bool final { return false; }

EXPRESSION_TYPE(None)
EXPRESSION_CATEGORY(0)
EXPRESSION_CATEGORY(UnExp)

[[nodiscard]] auto ToString() const -> std::string final;

Expand Down
6 changes: 5 additions & 1 deletion include/Oasis/Variable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef OASIS_VARIABLE_HPP
#define OASIS_VARIABLE_HPP

#include <stdexcept>
#include <string>

#include "LeafExpression.hpp"
Expand All @@ -27,7 +28,7 @@ class Variable : public LeafExpression<Variable> {
[[nodiscard]] virtual auto Equals(const Expression& other) const -> bool final;

EXPRESSION_TYPE(Variable)
EXPRESSION_CATEGORY(0)
EXPRESSION_CATEGORY(UnExp)

/**
* Gets the name of the variable.
Expand All @@ -37,10 +38,13 @@ class Variable : public LeafExpression<Variable> {
[[nodiscard]] auto GetName() const -> std::string;

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

static auto Specialize(const Expression& other) -> std::unique_ptr<Variable>;
static auto Specialize(const Expression& other, tf::Subflow& subflow) -> std::unique_ptr<Variable>;

auto Substitute(const Expression& var, const Expression& val) -> std::unique_ptr<Expression> override;

auto operator=(const Variable& other) -> Variable& = default;

private:
Expand Down
Loading

0 comments on commit ba69817

Please sign in to comment.