delpi  0.0.1
DElta-complete LP solver
Loading...
Searching...
No Matches
Expression.cpp
1
6#include "delpi/symbolic/Expression.h"
7
8#include <map>
9#include <sstream>
10#include <string>
11#include <unordered_map>
12#include <utility>
13#include <vector>
14
15#include "delpi/symbolic/ExpressionCell.h"
16#include "delpi/util/error.h"
17
18namespace delpi {
19
20Expression::Expression() : ptr_(ExpressionCell::New()) {}
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) {
29 ptr_ = e.ptr_;
30 return *this;
31}
32Expression& Expression::operator=(Expression&& e) noexcept {
33 ptr_ = std::move(e.ptr_);
34 return *this;
35}
36Expression::~Expression() {}
37
38std::vector<Variable> Expression::variables() const { return ptr_->variables(); }
39const Expression::Addends& Expression::addends() const { return ptr_->addends(); }
40
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>
45mpq_class Expression::Evaluate(const T& env) const {
46 return ptr_->Evaluate(env);
47}
48Expression Expression::Substitute(const SubstitutionMap& s) const { return ptr_->Substitute(s); }
49std::string Expression::ToString() const { return (std::stringstream{} << *this).str(); }
50std::ostream& Expression::Print(std::ostream& os) const { return ptr_->Print(os); }
51std::size_t Expression::use_count() const { return ptr_->use_count(); }
52
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");
57 ptr_->Multiply(o);
58 return *this;
59}
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");
64 ptr_->Divide(o);
65 return *this;
66}
67Expression Expression::operator*(const mpq_class& o) const {
68 Expression temp{*this};
69 return temp *= o;
70}
71Expression Expression::operator/(const mpq_class& o) const {
72 Expression temp{*this};
73 return temp /= o;
74}
75
76Expression& Expression::Add(const Variable& var, const mpq_class& coeff) {
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);
81 return *this;
82}
83
84Expression& Expression::Subtract(const Variable& var, const mpq_class& coeff) { return Add(var, -coeff); }
85
86Expression Expression::operator-() const { return *this * -1; }
87Expression Expression::operator+() const { return *this; }
88
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};
93 return temp += o;
94}
95
96Expression Expression::operator-(const Variable& o) const {
97 Expression temp{*this};
98 return temp -= o;
99}
100
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};
105 return temp += o;
106}
107
108Expression Expression::operator-(const Addend& o) const {
109 Expression temp{*this};
110 return temp -= o;
111}
112
113Expression& Expression::operator+=(const Expression& o) {
114 for (const auto& [var, coeff] : o.addends()) Add(var, coeff);
115 return *this;
116}
117Expression& Expression::operator-=(const Expression& o) {
118 for (const auto& [var, coeff] : o.addends()) Subtract(var, coeff);
119 return *this;
120}
121Expression Expression::operator+(const Expression& o) const {
122 Expression temp{*this};
123 return temp += o;
124}
125
126Expression Expression::operator-(const Expression& o) const {
127 Expression temp{*this};
128 return temp -= o;
129}
130
131Expression operator-(const Variable& var) { return Expression{Expression::Addend{var, -1}}; }
132
133Expression operator*(const mpq_class& lhs, const Expression& rhs) {
134 Expression temp{rhs};
135 return temp *= lhs;
136}
137Expression operator*(const mpq_class& lhs, const Variable& rhs) {
138 Expression temp{rhs};
139 return temp *= lhs;
140}
141Expression operator*(const Variable& lhs, const mpq_class& rhs) {
142 Expression temp{lhs};
143 return temp *= rhs;
144}
145Expression operator/(const Variable& lhs, const mpq_class& rhs) {
146 Expression temp{lhs};
147 return temp /= rhs;
148}
149Expression operator+(const Variable& lhs, const Expression& rhs) {
150 Expression temp(rhs);
151 return temp += lhs;
152}
153Expression operator-(const Variable& lhs, const Expression& rhs) {
154 Expression temp{lhs};
155 return temp -= rhs;
156}
157Expression operator+(const Expression::Addend& lhs, const Expression& rhs) {
158 Expression temp(rhs);
159 return temp += lhs;
160}
161Expression operator-(const Expression::Addend& lhs, const Expression& rhs) {
162 Expression temp{lhs};
163 return temp -= rhs;
164}
165
166std::ostream& operator<<(std::ostream& os, const Expression& e) { return e.Print(os); }
167
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;
170
171} // namespace delpi
Symbolic expression representing an addition between linear monomials.
Represents a symbolic form of an expression.
Definition Expression.h:37
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.
Definition Expression.h:143
Real symbolic variable.
Definition Variable.h:20
Global namespace for the delpi library.
LpRowSense operator-(const LpRowSense sense)
Invert the sense with delta > 0.