5#ifndef OASIS_BINARYEXPRESSION_HPP
6#define OASIS_BINARYEXPRESSION_HPP
28template <
typename MostSigOpT,
typename LeastSigOpT,
typename T>
31template <
template <
typename,
typename>
typename T>
40template <
template <
typename,
typename>
typename T>
44 if (ops.size() <= 1) {
48 using GeneralizedT = T<Expression, Expression>;
51 opsList.
resize(ops.size());
53 std::transform(ops.begin(), ops.end(), opsList.
begin(), [](
const auto& op) { return op->Copy(); });
58 opsList.
insert(i, std::move(node));
63 auto* result =
dynamic_cast<GeneralizedT*
>(opsList.
front().release());
82template <
template <IExpression, IExpression>
class DerivedT, IExpression MostSigOpT = Expression, IExpression LeastSigOpT = MostSigOpT>
85 using DerivedSpecialized = DerivedT<MostSigOpT, LeastSigOpT>;
86 using DerivedGeneralized = DerivedT<Expression, Expression>;
121 auto generalized = BuildFromVector<DerivedT>(opsVec);
134 if (this->
GetType() != other.GetType()) {
138 const auto otherGeneralized = other.Generalize();
139 const auto& otherBinaryGeneralized =
static_cast<const DerivedGeneralized&
>(*otherGeneralized);
141 bool mostSigOpMismatch =
false, leastSigOpMismatch =
false;
143 if (this->
HasMostSigOp() == otherBinaryGeneralized.HasMostSigOp()) {
144 if (
mostSigOp && otherBinaryGeneralized.HasMostSigOp()) {
145 mostSigOpMismatch = !
mostSigOp->Equals(otherBinaryGeneralized.GetMostSigOp());
148 mostSigOpMismatch =
true;
151 if (this->
HasLeastSigOp() == otherBinaryGeneralized.HasLeastSigOp()) {
152 if (this->
HasLeastSigOp() && otherBinaryGeneralized.HasLeastSigOp()) {
153 leastSigOpMismatch = !
leastSigOp->Equals(otherBinaryGeneralized.GetLeastSigOp());
156 mostSigOpMismatch =
true;
159 if (!mostSigOpMismatch && !leastSigOpMismatch) {
171 otherBinaryGeneralized.Flatten(otherFlattened);
173 for (
const auto& thisOperand : thisFlattened) {
174 if (
std::find_if(otherFlattened.begin(), otherFlattened.end(), [&thisOperand](
const auto& otherOperand) {
175 return thisOperand->Equals(*otherOperand);
177 == otherFlattened.end()) {
187 DerivedGeneralized generalized;
190 generalized.SetMostSigOp(*this->
mostSigOp->Copy());
194 generalized.SetLeastSigOp(*this->
leastSigOp->Copy());
202 return Generalize()->Integrate(integrationVariable);
207 if (this->
GetType() != other.GetType()) {
212 const auto& otherBinaryGeneralized =
static_cast<const DerivedGeneralized&
>(*otherGeneralized);
214 if (this->
HasMostSigOp() == otherBinaryGeneralized.HasMostSigOp()) {
215 if (this->
HasMostSigOp() && otherBinaryGeneralized.HasMostSigOp()) {
216 if (!
mostSigOp->StructurallyEquivalent(otherBinaryGeneralized.GetMostSigOp())) {
222 if (this->
HasLeastSigOp() == otherBinaryGeneralized.HasLeastSigOp()) {
223 if (this->
HasLeastSigOp() && otherBinaryGeneralized.HasLeastSigOp()) {
224 if (!
leastSigOp->StructurallyEquivalent(otherBinaryGeneralized.GetLeastSigOp())) {
247 if (this->
mostSigOp->template Is<DerivedGeneralized>()) {
248 auto generalizedMostSigOp = this->
mostSigOp->Generalize();
249 const auto&
mostSigOp =
static_cast<const DerivedGeneralized&
>(*generalizedMostSigOp);
257 if (this->
leastSigOp->template Is<DerivedGeneralized>()) {
258 auto generalizedLeastSigOp = this->
leastSigOp->Generalize();
259 const auto&
leastSigOp =
static_cast<const DerivedGeneralized&
>(*generalizedLeastSigOp);
309 template <
typename T>
323 if (
auto castedOp = Oasis::RecursiveCast<MostSigOpT>(op); castedOp) {
335 template <
typename T>
349 if (
auto castedOp = Oasis::RecursiveCast<LeastSigOpT>(op); castedOp) {
362 DerivedT<Expression, Expression> comb = DerivedT<Expression, Expression> { *left, *right };
365 auto simplified = comb.Accept(simplifyVisitor);
367 return comb.Generalize();
369 return std::move(simplified.value());
385 const auto& derivedGeneralized =
dynamic_cast<const DerivedGeneralized&
>(*generalized);
386 return visitor.Visit(derivedGeneralized);
A binary expression.
Definition BinaryExpression.hpp:83
auto Copy() const -> std::unique_ptr< Expression > final
Copies this expression.
Definition BinaryExpression.hpp:127
BinaryExpression(const BinaryExpression &other)
Definition BinaryExpression.hpp:90
std::unique_ptr< LeastSigOpT > leastSigOp
Definition BinaryExpression.hpp:390
auto AcceptInternal(Visitor &visitor) const -> any override
This function serializes the expression object.
Definition BinaryExpression.hpp:382
auto Substitute(const Expression &var, const Expression &val) -> std::unique_ptr< Expression > override
Definition BinaryExpression.hpp:357
auto GetLeastSigOp() const -> const LeastSigOpT &
Gets the least significant operand of this expression.
Definition BinaryExpression.hpp:281
auto operator=(const BinaryExpression &other) -> BinaryExpression &=default
auto SetLeastSigOp(const T &op) -> bool
Sets the least significant operand of this expression.
Definition BinaryExpression.hpp:337
auto Integrate(const Expression &integrationVariable) const -> std::unique_ptr< Expression > override
Attempts to integrate this expression using integration rules.
Definition BinaryExpression.hpp:200
auto Generalize() const -> std::unique_ptr< Expression > final
Converts this expression to a more general expression.
Definition BinaryExpression.hpp:185
auto GetMostSigOp() const -> const MostSigOpT &
Gets the most significant operand of this expression.
Definition BinaryExpression.hpp:271
std::unique_ptr< MostSigOpT > mostSigOp
Definition BinaryExpression.hpp:389
auto SwapOperands() const -> DerivedT< LeastSigOpT, MostSigOpT >
Swaps the operands of this expression.
Definition BinaryExpression.hpp:375
auto SetMostSigOp(const T &op) -> bool
Sets the most significant operand of this expression.
Definition BinaryExpression.hpp:311
auto StructurallyEquivalent(const Expression &other) const -> bool final
Checks whether this expression is structurally equivalent to another expression.
Definition BinaryExpression.hpp:205
auto Flatten(std::vector< std::unique_ptr< Expression > > &out) const -> void
Flattens this expression.
Definition BinaryExpression.hpp:244
auto HasLeastSigOp() const -> bool
Gets whether this expression has a least significant operand.
Definition BinaryExpression.hpp:300
BinaryExpression(const Op1T &op1, const Op2T &op2, const OpsT &... ops)
Definition BinaryExpression.hpp:108
BinaryExpression()=default
auto Equals(const Expression &other) const -> bool final
Compares this expression to another expression for equality.
Definition BinaryExpression.hpp:132
BinaryExpression(const MostSigOpT &mostSigOp, const LeastSigOpT &leastSigOp)
Definition BinaryExpression.hpp:101
auto HasMostSigOp() const -> bool
Gets whether this expression has a most significant operand.
Definition BinaryExpression.hpp:291
An expression.
Definition Expression.hpp:63
virtual auto Copy() const -> std::unique_ptr< Expression >=0
Copies this expression.
virtual auto GetCategory() const -> uint32_t
Gets the category of this expression.
Definition Expression.cpp:221
virtual auto GetType() const -> ExpressionType
Gets the type of this expression.
Definition Expression.cpp:236
Definition SimplifyVisitor.hpp:30
Definition BinaryExpression.hpp:32
An expression concept.
Definition Concepts.hpp:30
A concept for an operand of a binary expression.
Definition BinaryExpression.hpp:29
Checks if type T is same as any of the provided types in U.
Definition Concepts.hpp:53
T emplace_back(T... args)
auto BuildFromVector(const std::vector< std::unique_ptr< Expression > > &ops) -> std::unique_ptr< T< Expression, Expression > >
Builds a reasonably balanced binary expression from a vector of operands.
Definition BinaryExpression.hpp:42
boost::anys::unique_any any
Definition Expression.hpp:15
@ Commutative
Definition Expression.hpp:51
@ Associative
Definition Expression.hpp:50