6#include "delpi/symbolic/Expression.h"
11#include <unordered_map>
15#include "delpi/symbolic/ExpressionCell.h"
16#include "delpi/util/error.h"
21Expression::Expression(Variable var) : ptr_(ExpressionCell::New(std::move(var))) {}
22Expression::Expression(Addend addend) : ptr_(ExpressionCell::New(std::move(addend))) {}
23Expression::Expression(Addends addends) : ptr_{ExpressionCell::New(std::move(addends))} {}
24Expression::Expression(std::vector<Addend> addends)
25 : ptr_{ExpressionCell::New(Addends{addends.begin(), addends.end()})} {}
26Expression::Expression(
const Expression& e) : ptr_{e.ptr_} {}
27Expression::Expression(Expression&& e) noexcept : ptr_{std::move(e.ptr_)} {}
28Expression& Expression::operator=(
const Expression& e) {
32Expression& Expression::operator=(Expression&& e)
noexcept {
33 ptr_ = std::move(e.ptr_);
36Expression::~Expression() {}
38std::vector<Variable> Expression::variables()
const {
return ptr_->variables(); }
39const Expression::Addends& Expression::addends()
const {
return ptr_->addends(); }
41bool Expression::equal_to(
const Expression& o)
const noexcept {
return ptr_->equal_to(*o.ptr_); }
42bool Expression::less(
const Expression& o)
const noexcept {
return ptr_->less(*o.ptr_); }
43std::size_t Expression::hash() const noexcept {
return ptr_->hash(); }
44template <MapFromTo<Variable, mpq_
class> T>
46 return ptr_->Evaluate(env);
49std::string Expression::ToString()
const {
return (std::stringstream{} << *
this).str(); }
51std::size_t Expression::use_count()
const {
return ptr_->use_count(); }
53Expression& Expression::operator*=(
const mpq_class& o) {
54 if (o == 1)
return *
this;
55 if (ptr_->use_count() != 1) ptr_ = ExpressionCell::Copy(*ptr_);
56 DELPI_ASSERT(ptr_->use_count() == 1,
"The expression must be the only owner to modify its expression cell");
60Expression& Expression::operator/=(
const mpq_class& o) {
61 if (o == 1)
return *
this;
62 if (ptr_->use_count() != 1) ptr_ = ExpressionCell::Copy(*ptr_);
63 DELPI_ASSERT(ptr_->use_count() == 1,
"The expression must be the only owner to modify its expression cell");
67Expression Expression::operator*(
const mpq_class& o)
const {
68 Expression temp{*
this};
71Expression Expression::operator/(
const mpq_class& o)
const {
72 Expression temp{*
this};
77 if (coeff == 0)
return *
this;
78 if (
ptr_->use_count() != 1)
ptr_ = ExpressionCell::Copy(*
ptr_);
79 DELPI_ASSERT(
ptr_->use_count() == 1,
"The expression must be the only owner to modify its expression cell");
80 ptr_->Add(var, coeff);
86Expression Expression::operator-()
const {
return *
this * -1; }
87Expression Expression::operator+()
const {
return *
this; }
89Expression& Expression::operator+=(
const Variable& o) {
return Add(o, 1); }
90Expression& Expression::operator-=(
const Variable& o) {
return Subtract(o, 1); }
91Expression Expression::operator+(
const Variable& o)
const {
92 Expression temp{*
this};
96Expression Expression::operator-(
const Variable& o)
const {
97 Expression temp{*
this};
101Expression& Expression::operator+=(
const Addend& o) {
return Add(o.first, o.second); }
102Expression& Expression::operator-=(
const Addend& o) {
return Subtract(o.first, o.second); }
103Expression Expression::operator+(
const Addend& o)
const {
104 Expression temp{*
this};
108Expression Expression::operator-(
const Addend& o)
const {
109 Expression temp{*
this};
113Expression& Expression::operator+=(
const Expression& o) {
114 for (
const auto& [var, coeff] : o.addends()) Add(var, coeff);
117Expression& Expression::operator-=(
const Expression& o) {
118 for (
const auto& [var, coeff] : o.addends()) Subtract(var, coeff);
121Expression Expression::operator+(
const Expression& o)
const {
122 Expression temp{*
this};
126Expression Expression::operator-(
const Expression& o)
const {
127 Expression temp{*
this};
131Expression
operator-(
const Variable& var) {
return Expression{Expression::Addend{var, -1}}; }
133Expression operator*(
const mpq_class& lhs,
const Expression& rhs) {
134 Expression temp{rhs};
137Expression operator*(
const mpq_class& lhs,
const Variable& rhs) {
138 Expression temp{rhs};
141Expression operator*(
const Variable& lhs,
const mpq_class& rhs) {
142 Expression temp{lhs};
145Expression operator/(
const Variable& lhs,
const mpq_class& rhs) {
146 Expression temp{lhs};
149Expression operator+(
const Variable& lhs,
const Expression& rhs) {
150 Expression temp(rhs);
153Expression
operator-(
const Variable& lhs,
const Expression& rhs) {
154 Expression temp{lhs};
157Expression operator+(
const Expression::Addend& lhs,
const Expression& rhs) {
158 Expression temp(rhs);
161Expression
operator-(
const Expression::Addend& lhs,
const Expression& rhs) {
162 Expression temp{lhs};
166std::ostream& operator<<(std::ostream& os,
const Expression& e) {
return e.Print(os); }
168template mpq_class Expression::Evaluate(
const std::map<Variable, mpq_class>& env)
const;
169template mpq_class Expression::Evaluate(
const std::unordered_map<Variable, mpq_class>& env)
const;
Symbolic expression representing an addition between linear monomials.
Represents a symbolic form of an expression.
Expression & Subtract(const Variable &var, const mpq_class &coeff)
Subtract a linear monomial , where is a constant and is a Variable, to the current expression.
Expression Substitute(const SubstitutionMap &s) const
Create a copy of this expression, replacing all occurrences of the variables in s with corresponding ...
std::ostream & Print(std::ostream &os) const
Print a string representation of this class to the provided os.
Expression & Add(const Variable &var, const mpq_class &coeff)
Add a linear monomial , where is a constant and is a Variable, to the current expression.
mpq_class Evaluate(const T &env={}) const
Evaluates using a given environment (by default, an empty environment).
intrusive_ptr< ExpressionCell > ptr_
Internal pointer to the ExpressionCell.
Global namespace for the delpi library.
LpRowSense operator-(const LpRowSense sense)
Invert the sense with delta > 0.