delpi  0.0.1
DElta-complete LP solver
Loading...
Searching...
No Matches
Formula.cpp
1
6#include "delpi/symbolic/Formula.h"
7
8#include <map>
9#include <ostream>
10#include <unordered_map>
11#include <utility>
12
13#include "delpi/util/error.h"
14#include "delpi/util/hash.hpp"
15
16namespace delpi {
17
18Formula::Formula(Expression expression, const FormulaKind kind, mpq_class rhs)
19 : expression_{std::move(expression)}, kind_{kind}, rhs_{std::move(rhs)} {}
20
21Formula Formula::Substitute(const Expression::SubstitutionMap& s) const {
22 return Formula{expression_.Substitute(s), kind_, rhs_};
23}
24template <MapFromTo<Variable, mpq_class> T>
25bool Formula::Evaluate(const T& env) const {
26 const mpq_class value{expression_.Evaluate(env)};
27 switch (kind_) {
28 case FormulaKind::Eq:
29 return value == rhs_;
31 return value != rhs_;
32 case FormulaKind::Lt:
33 return value < rhs_;
35 return value <= rhs_;
36 case FormulaKind::Gt:
37 return value > rhs_;
39 return value >= rhs_;
40 default:
41 DELPI_UNREACHABLE();
42 }
43}
44
45bool Formula::equal_to(const Formula& o) const noexcept {
46 if (this == &o) return true;
47 if (kind_ != o.kind_) return false;
48 if (rhs_ != o.rhs_) return false;
49 return expression_.equal_to(o.expression_);
50}
51bool Formula::less(const Formula& o) const noexcept {
52 if (this == &o) return false;
53 if (kind_ != o.kind_) return kind_ < o.kind_;
54 if (rhs_ != o.rhs_) return rhs_ < o.rhs_;
55 return expression_.less(o.expression_);
56}
57std::size_t Formula::hash() const noexcept { return hash::hash_combine(expression_.hash(), kind_, rhs_); }
58
59Formula Formula::operator-() const { return Formula{-expression_, -kind_, -rhs_}; }
60Formula Formula::operator!() const { return Formula{expression_, !kind_, rhs_}; }
61std::strong_ordering Formula::operator<=>(const Formula& o) const {
62 if (less(o)) return std::strong_ordering::less;
63 if (o.less(*this)) return std::strong_ordering::greater;
64 return std::strong_ordering::equal;
65}
66
67Formula operator==(const Variable& lhs, const Variable& rhs) { return Formula{lhs - rhs, FormulaKind::Eq, 0}; }
68Formula operator!=(const Variable& lhs, const Variable& rhs) { return Formula{lhs - rhs, FormulaKind::Neq, 0}; }
69Formula operator<(const Variable& lhs, const Variable& rhs) { return Formula{lhs - rhs, FormulaKind::Lt, 0}; }
70Formula operator<=(const Variable& lhs, const Variable& rhs) { return Formula{lhs - rhs, FormulaKind::Leq, 0}; }
71Formula operator>(const Variable& lhs, const Variable& rhs) { return Formula{lhs - rhs, FormulaKind::Gt, 0}; }
72Formula operator>=(const Variable& lhs, const Variable& rhs) { return Formula{lhs - rhs, FormulaKind::Geq, 0}; }
73
74Formula operator==(const Expression& lhs, const Expression& rhs) { return Formula{lhs - rhs, FormulaKind::Eq, 0}; }
75Formula operator!=(const Expression& lhs, const Expression& rhs) { return Formula{lhs - rhs, FormulaKind::Neq, 0}; }
76Formula operator<(const Expression& lhs, const Expression& rhs) { return Formula{lhs - rhs, FormulaKind::Lt, 0}; }
77Formula operator<=(const Expression& lhs, const Expression& rhs) { return Formula{lhs - rhs, FormulaKind::Leq, 0}; }
78Formula operator>(const Expression& lhs, const Expression& rhs) { return Formula{lhs - rhs, FormulaKind::Gt, 0}; }
79Formula operator>=(const Expression& lhs, const Expression& rhs) { return Formula{lhs - rhs, FormulaKind::Geq, 0}; }
80
81Formula operator==(mpq_class lhs, const Expression& rhs) { return Formula{rhs, FormulaKind::Eq, std::move(lhs)}; }
82Formula operator!=(mpq_class lhs, const Expression& rhs) { return Formula{rhs, FormulaKind::Neq, std::move(lhs)}; }
83Formula operator<(mpq_class lhs, const Expression& rhs) { return Formula{rhs, FormulaKind::Gt, std::move(lhs)}; }
84Formula operator<=(mpq_class lhs, const Expression& rhs) { return Formula{rhs, FormulaKind::Geq, std::move(lhs)}; }
85Formula operator>(mpq_class lhs, const Expression& rhs) { return Formula{rhs, FormulaKind::Lt, std::move(lhs)}; }
86Formula operator>=(mpq_class lhs, const Expression& rhs) { return Formula{rhs, FormulaKind::Leq, std::move(lhs)}; }
87
88Formula operator==(const Expression& lhs, mpq_class rhs) { return Formula{lhs, FormulaKind::Eq, std::move(rhs)}; }
89Formula operator!=(const Expression& lhs, mpq_class rhs) { return Formula{lhs, FormulaKind::Neq, std::move(rhs)}; }
90Formula operator<(const Expression& lhs, mpq_class rhs) { return Formula{lhs, FormulaKind::Lt, std::move(rhs)}; }
91Formula operator<=(const Expression& lhs, mpq_class rhs) { return Formula{lhs, FormulaKind::Leq, std::move(rhs)}; }
92Formula operator>(const Expression& lhs, mpq_class rhs) { return Formula{lhs, FormulaKind::Gt, std::move(rhs)}; }
93Formula operator>=(const Expression& lhs, mpq_class rhs) { return Formula{lhs, FormulaKind::Geq, std::move(rhs)}; }
94
95std::ostream& operator<<(std::ostream& os, const Formula& formula) {
96 return os << "(" << formula.expression() << " " << formula.kind() << " " << formula.rhs() << ")";
97}
98
99template bool Formula::Evaluate(const std::map<Variable, mpq_class>& env) const;
100template bool Formula::Evaluate(const std::unordered_map<Variable, mpq_class>& env) const;
101
102} // namespace delpi
Represents a symbolic form of an expression.
Definition Expression.h:37
Symbolic formula used to represent a constraint in the LP problem.
Definition Formula.h:32
bool Evaluate(const T &env) const
Evaluates the formula using a given environment (by default, an empty environment).
Definition Formula.cpp:25
Expression expression_
Left-hand side expression.
Definition Formula.h:86
FormulaKind kind_
Kind of the formula .
Definition Formula.h:87
mpq_class rhs_
Right-hand side constant.
Definition Formula.h:88
Formula Substitute(const Expression::SubstitutionMap &s) const
Create a copy of this formula with the expression having all occurrences of the variables in s replac...
Definition Formula.cpp:21
Global namespace for the delpi library.
FormulaKind
Kinds of symbolic formulas.
Definition FormulaKind.h:14