delpi  0.0.1
DElta-complete LP solver
Loading...
Searching...
No Matches
VariableSet.h
1
7#pragma once
8
9#include <algorithm>
10#include <functional>
11#include <iosfwd>
12#include <limits>
13#include <vector>
14
15#include "delpi/symbolic/Variable.h"
16#include "delpi/util/concepts.h"
17
18namespace delpi {
19
33class VariableSet {
34 public:
35 using Id = Variable::Id;
36
38 VariableSet() : min_id_{std::numeric_limits<Id>::max()} {}
44 template <TypedIterable<Variable> T>
45 explicit VariableSet(const T& vars) : VariableSet{} {
46 Insert(vars);
47 }
48
56 template <std::same_as<Variable>... Vars>
57 explicit VariableSet(const Variable& var, const Vars&... vars) : VariableSet{} {
58 Insert(var, vars...);
59 }
60
62 [[nodiscard]] Id min_id() const { return min_id_; }
64 [[nodiscard]] Id max_id() const { return vars_.size() + min_id_; }
66 [[nodiscard]] std::size_t size() const;
68 [[nodiscard]] std::size_t capacity() const { return vars_.size(); }
70 [[nodiscard]] bool empty() const;
72 [[nodiscard]] std::vector<Variable> variables() const;
73
80 [[nodiscard]] Variable Get(Id id) const;
87 [[nodiscard]] bool Contains(const Variable& var) const { return Contains(var.id()); }
95 bool Insert(const Variable& var) { return Insert(var.id()); }
102 template <TypedIterable<Variable> T>
103 void Insert(const T& vars) {
104 using Comparator = std::less<Variable>;
105 // If the set is empty, initialise it with min_id_ = min(vars.id) and size m = max(vars.id) - min_id_ + 1
106 if (min_id_ == std::numeric_limits<Id>::max()) {
107 min_id_ = std::ranges::min_element(vars, Comparator{})->id();
108 vars_.resize(std::ranges::max_element(vars, Comparator{})->id() - min_id_ + 1, false);
109 for (const Variable var : vars) vars_.at(var.id() - min_id_) = true;
110 return;
111 }
112 // If the set is not empty, resize it to the new range and insert the variables
113 // First compute the new min_id and max_id comparing with the current min_id and max_id
114 // Then resize the vector to the new range m = new_max - new_min + 1
115 const Id new_min = std::min(std::ranges::min_element(vars, Comparator{})->id(), min_id_);
116 const Id new_max = std::max(std::ranges::max_element(vars, Comparator{})->id(), vars_.size() + min_id_ - 1);
117 const std::size_t max_diff = new_max - (vars_.size() + min_id_ - 1);
118 const std::size_t old_size = vars_.size();
119 vars_.resize(new_max - new_min + 1);
120 // If the lower bound of the new range is less than the current min_id, rotate the vector to the left by max_diff
121 if (new_min < min_id_) {
122 std::rotate(vars_.begin(), vars_.begin() + static_cast<std::int64_t>(old_size),
123 vars_.end() - static_cast<std::int64_t>(max_diff));
124 min_id_ = new_min;
125 }
126 for (const Variable var : vars) vars_.at(var.id() - min_id_) = true;
127 }
128
137 template <std::same_as<Variable>... Vars>
138 void Insert(const Variable& var, const Vars&... vars) {
139 Insert(var);
140 Insert(vars...);
141 }
142
149 bool Remove(const Variable& var) { return Remove(var.id()); }
156 template <TypedIterable<Variable> T>
157 void Remove(const T& vars) {
158 for (const Variable& var : vars) Remove(var);
159 }
160
167 template <std::same_as<Variable>... Vars>
168 void Remove(const Variable& var, const Vars&... vars) {
169 Remove(var);
170 Remove(vars...);
171 }
172
173 void Clear();
174
175 private:
182 [[nodiscard]] bool Contains(Id id) const;
189 bool Insert(Id id);
196 bool Remove(Id id);
197
199 std::vector<bool> vars_;
200};
201
202std::ostream& operator<<(std::ostream& os, const VariableSet& var_set);
203
204} // namespace delpi
205
206#ifdef DELPI_INCLUDE_FMT
207
208#include "delpi/util/logging.h"
209
210OSTREAM_FORMATTER(delpi::VariableSet)
211
212#endif
Set of variables optimised for fast access at the cost of memory.
Definition VariableSet.h:33
Id min_id_
Minimum id of the variables in the set.
bool empty() const
@checked{empty, variable set}
bool Remove(const Variable &var)
Remove a var from the set.
VariableSet(const Variable &var, const Vars &... vars)
Construct a new variable set from a sequence of variables.
Definition VariableSet.h:57
void Remove(const T &vars)
Remove a range of vars from the set.
VariableSet(const T &vars)
Construct a new variable set from a range of vars.
Definition VariableSet.h:45
bool Contains(const Variable &var) const
Check if the var is in the set.
Definition VariableSet.h:87
void Clear()
Clear the set of all variables.
void Remove(const Variable &var, const Vars &... vars)
Remove a sequence of variables from the set.
std::vector< bool > vars_
Vector tracking the presence of each variable in the set.
void Insert(const Variable &var, const Vars &... vars)
Insert a sequence of variables to the set.
Variable Get(Id id) const
Use the id to get the variable in the set, if it exists.
void Insert(const T &vars)
Insert a range of vars to the set.
bool Insert(const Variable &var)
Insert a var to the set.
Definition VariableSet.h:95
Real symbolic variable.
Definition Variable.h:20
Global namespace for the delpi library.