OASIS
Open Algebra Software
Loading...
Searching...
No Matches
BoundedUnaryExpression.hpp
Go to the documentation of this file.
1//
2// Created by Matthew McCall on 4/30/24.
3//
4
5#ifndef OASIS_BOUNDEDUNARYEXPRESSION_HPP
6#define OASIS_BOUNDEDUNARYEXPRESSION_HPP
7
8#include <cassert>
9
10#include "Bounds.hpp"
11#include "Expression.hpp"
12#include "Visit.hpp"
13
14namespace Oasis {
15
25template <template <IExpression, IExpression, IExpression> class DerivedT, IExpression OperandT, IExpression LowerBoundT = Expression, IExpression UpperBoundT = LowerBoundT>
26class BoundedUnaryExpression : public BoundedExpression<LowerBoundT, UpperBoundT> {
27
28 using DerivedSpecialized = DerivedT<OperandT, LowerBoundT, UpperBoundT>;
29 using DerivedGeneralized = DerivedT<Expression, Expression, Expression>;
30
31public:
33
35 {
36 if (other.HasOperand())
37 SetOperand(other.GetOperand());
38 if (other.HasLowerBound())
40 if (other.HasUpperBound())
42 }
43
44 BoundedUnaryExpression(const OperandT& operand, const LowerBoundT& lowerBound, const UpperBoundT& upperBound)
45 {
46 SetOperand(operand);
47 SetLowerBound(lowerBound);
48 SetUpperBound(upperBound);
49 }
50
51 [[nodiscard]] auto Copy() const -> std::unique_ptr<Expression> final
52 {
53 return std::make_unique<DerivedSpecialized>(*static_cast<const DerivedSpecialized*>(this));
54 }
55
56 auto Copy(tf::Subflow&) const -> std::unique_ptr<Expression> final
57 {
58 // TODO: Actually implement
59 return std::make_unique<DerivedSpecialized>(*static_cast<const DerivedSpecialized*>(this));
60 }
61
62 [[nodiscard]] auto Differentiate(const Expression& differentiationVariable) const -> std::unique_ptr<Expression> override
63 {
64 return this->Generalize()->Differentiate(differentiationVariable);
65 }
66
67 [[nodiscard]] auto Equals(const Expression& other) const -> bool final
68 {
69
70 // TODO: Reimplement now that Specialize is gone
71 // if (const auto otherExpression = DerivedSpecialized::Specialize(other); otherExpression != nullptr) {
72 // return HasOperand() == otherExpression->HasOperand()
73 // && this->HasLowerBound() == otherExpression->HasLowerBound()
74 // && this->HasUpperBound() == otherExpression->HasUpperBound();
75 // }
76
77 return false;
78 }
79
80 [[nodiscard]] auto HasOperand() const -> bool
81 {
82 return operand != nullptr;
83 }
84
85 [[nodiscard]] auto GetOperand() const -> const OperandT&
86 {
87 assert(HasOperand() && "Operand is not set.");
88 return *operand;
89 }
90
91 template <typename T>
93 void SetOperand(const T& expr)
94 {
95 if constexpr (std::is_same_v<T, OperandT>) {
96 operand = std::make_unique<OperandT>(expr);
97 } else {
98 operand = expr.Copy();
99 }
100 }
101
102 auto Substitute(const Expression& var, const Expression& val) -> std::unique_ptr<Expression> override
103 {
104 std::unique_ptr<Expression> newOperand = operand->Substitute(var, val);
105 std::unique_ptr<Expression> newLowerBound = this->GetLowerBound().Substitute(var, val);
106 std::unique_ptr<Expression> newUpperBound = this->GetUpperBound().Substitute(var, val);
107 DerivedGeneralized substituted = DerivedGeneralized { operand, newLowerBound, newUpperBound };
108 return substituted.Copy();
109 }
110
112
113 void Serialize(SerializationVisitor& visitor) const override
114 {
115 const auto generalized = this->Generalize();
116 const auto& derivedGeneralized = dynamic_cast<const DerivedGeneralized&>(*generalized);
117 visitor.Serialize(derivedGeneralized);
118 }
119
120private:
122};
123
124}
125
126#endif // OASIS_BOUNDEDUNARYEXPRESSION_HPP
A concept base class for both Unary and BoundedBinary expressions.
Definition BoundedExpression.hpp:23
auto GetLowerBound() const -> const LowerBoundT &
Definition BoundedExpression.hpp:51
auto GetUpperBound() const -> const UpperBoundT &
Definition BoundedExpression.hpp:57
auto HasLowerBound() const -> bool
Definition BoundedExpression.hpp:41
void SetLowerBound(const T &expr)
Definition BoundedExpression.hpp:65
auto HasUpperBound() const -> bool
Definition BoundedExpression.hpp:46
void SetUpperBound(const T &expr)
Definition BoundedExpression.hpp:76
A concept for an operand of a unary expression with bounds.
Definition BoundedUnaryExpression.hpp:26
void SetOperand(const T &expr)
Definition BoundedUnaryExpression.hpp:93
auto Copy() const -> std::unique_ptr< Expression > final
Copies this expression.
Definition BoundedUnaryExpression.hpp:51
auto GetOperand() const -> const OperandT &
Definition BoundedUnaryExpression.hpp:85
auto Substitute(const Expression &var, const Expression &val) -> std::unique_ptr< Expression > override
Definition BoundedUnaryExpression.hpp:102
auto Copy(tf::Subflow &) const -> std::unique_ptr< Expression > final
Definition BoundedUnaryExpression.hpp:56
BoundedUnaryExpression(const BoundedUnaryExpression &other)
Definition BoundedUnaryExpression.hpp:34
auto operator=(const BoundedUnaryExpression &other) -> BoundedUnaryExpression &=default
auto HasOperand() const -> bool
Definition BoundedUnaryExpression.hpp:80
void Serialize(SerializationVisitor &visitor) const override
Definition BoundedUnaryExpression.hpp:113
auto Differentiate(const Expression &differentiationVariable) const -> std::unique_ptr< Expression > override
Tries to differentiate this function.
Definition BoundedUnaryExpression.hpp:62
BoundedUnaryExpression(const OperandT &operand, const LowerBoundT &lowerBound, const UpperBoundT &upperBound)
Definition BoundedUnaryExpression.hpp:44
auto Equals(const Expression &other) const -> bool final
Compares this expression to another expression for equality.
Definition BoundedUnaryExpression.hpp:67
An expression.
Definition Expression.hpp:62
virtual auto Generalize() const -> std::unique_ptr< Expression >
Converts this expression to a more general expression.
Definition Expression.cpp:225
Checks if type T is same as any of the provided types in U.
Definition Concepts.hpp:51
T is_same_v
Definition Add.hpp:11