carl  24.04
Computer ARithmetic Library
VariablePool.h
Go to the documentation of this file.
1 /**
2  * @file VariablePool.h
3  * @author Sebastian Junges
4  */
5 
6 #pragma once
7 
8 #include <carl-common/config.h>
10 #include "Variable.h"
11 
12 #include <array>
13 #include <map>
14 #include <mutex>
15 #include <string>
16 #include <vector>
17 
18 namespace carl {
19 
20 /**
21  * This class generates new variables and stores human-readable names for them.
22  *
23  * As we want only a single unique VariablePool and need global access to it, it is implemented as a singleton.
24  *
25  * All methods that modify the pool, that are getInstance(), get_fresh_variable() and set_name(), are thread-safe.
26  */
27 class VariablePool : public Singleton<VariablePool> {
29 
30 private:
31  /**
32  * Contains the id of the next variable to be created for each type.
33  * As such, is also a counter of the variables that exist.
34  */
35  std::array<std::size_t, static_cast<std::size_t>(VariableType::TYPE_SIZE)> mNextIDs;
36 
37  /**
38  * Mutex for calling get_fresh_variable().
39  */
40  mutable std::mutex freshVarMutex;
41 
42  /**
43  * Mutex for calling setVariableName().
44  */
45  mutable std::mutex set_nameMutex;
46 
47  std::size_t& nextID(VariableType vt) noexcept {
48  assert(static_cast<std::size_t>(vt) < mNextIDs.size());
49  return mNextIDs[static_cast<std::size_t>(vt)];
50  }
51  std::size_t nextID(VariableType vt) const noexcept {
52  assert(static_cast<std::size_t>(vt) < mNextIDs.size());
53  return mNextIDs[static_cast<std::size_t>(vt)];
54  }
55 
56  /**
57  * Contains persistent variables that are restored after clear was called.
58  */
59  std::vector<std::pair<Variable, std::string>> mPersistentVariables;
60 
61  /**
62  * Stores human-readable names for variables that can be set via setVariableName().
63  */
64  std::map<Variable, std::string> mVariableNames;
65 
66  /**
67  * Stores a prefix for printing variables that have no human-readable name.
68  */
69  std::string mVariablePrefix;
70 
71 #ifdef THREAD_SAFE
72 #define FRESHVAR_LOCK_GUARD std::lock_guard<std::mutex> lock1(freshVarMutex);
73 #define SETNAME_LOCK_GUARD std::lock_guard<std::mutex> lock2(set_nameMutex);
74 #else
75 #define FRESHVAR_LOCK_GUARD
76 #define SETNAME_LOCK_GUARD
77 #endif
78 
79 protected:
80  /**
81  * Private default constructor.
82  */
83  VariablePool() noexcept;
84 
85  /**
86  * Get a variable which was not used before.
87  * This method is thread-safe.
88  * @param type Type for the new variable.
89  * @return A new variable.
90  */
91  Variable get_fresh_variable(VariableType type = VariableType::VT_REAL) noexcept;
92 
93  /**
94  * Get a variable with was not used before and set a name for it.
95  * This method is thread-safe.
96  * @param name Name for the new variable.
97  * @param type Type for the new variable.
98  * @return A new variable.
99  */
100  Variable get_fresh_variable(const std::string& name, VariableType type = VariableType::VT_REAL);
101 
102 public:
103  Variable get_fresh_persistent_variable(VariableType type = VariableType::VT_REAL) noexcept;
104  Variable get_fresh_persistent_variable(const std::string& name, VariableType type = VariableType::VT_REAL);
105 
106  /**
107  * Clears everything already created in this pool.
108  */
109  void clear() noexcept {
110  mVariableNames.clear();
111  mNextIDs.fill(1);
112  for (const auto& pv : mPersistentVariables) {
113  Variable v = pv.first;
114  while (nextID(v.type()) < v.id()) {
116  }
117  if (!pv.second.empty()) {
118  get_fresh_variable(pv.second, v.type());
119  } else {
121  }
122  }
123  }
124 
125  /**
126  * Searches in the friendly names list for a variable with the given name.
127  * @param name The friendly variable name to look for.
128  * @return The first variable with that friendly name.
129  */
130  Variable find_variable_with_name(const std::string& name) const noexcept;
131  /**
132  * Get a human-readable name for the given variable.
133  * If the given Variable is Variable::NO_VARIABLE, "NO_VARIABLE" is returned.
134  * If friendlyVarName is true, the name that was set via setVariableName() for this Variable, if there is any, is returned.
135  * Otherwise "x_<id>" is returned, id being the internal id of the Variable.
136  * @param v Variable.
137  * @param variableName Flag, if a name set via setVariableName shall be considered.
138  * @return Some name for the Variable.
139  */
140  std::string get_name(Variable v, bool variableName = true) const;
141  /**
142  * Add a name for a given Variable.
143  * This method is thread-safe.
144  * @param v Variable.
145  * @param name Some string naming the variable.
146  */
147  void set_name(Variable v, const std::string& name);
148 
149  /**
150  * Sets the prefix used when printing anonymous variables.
151  * The default is "_", hence they look like "_x_5".
152  * @param prefix Prefix for anonymous variable names.
153  */
154  void set_prefix(std::string prefix = "_") noexcept {
155  mVariablePrefix = std::move(prefix);
156  }
157 
158  // /**
159  // * Returns the number of variables initialized by the pool.
160  // * @return Number of variables.
161  // */
162  // std::size_t nrVariables(VariableType type = VariableType::VT_REAL) const noexcept {
163  // return nextID(type) - 1;
164  // }
165 
166  // /**
167  // * Print variable names to the stream.
168  // */
169  // void printVariableNamesToStream(std::ostream& os) {
170  // for (auto const& v : mVariableNames) {
171  // os << v.second << " ";
172  // }
173  // }
174 
175  friend Variable fresh_variable(VariableType vt) noexcept;
176  friend Variable fresh_variable(const std::string& name, VariableType vt);
177 };
178 
179 inline Variable fresh_variable(VariableType vt) noexcept {
181 }
182 inline Variable fresh_variable(const std::string& name, VariableType vt) {
184 }
185 
188 }
189 inline Variable fresh_bitvector_variable(const std::string& name) {
191 }
192 inline Variable fresh_boolean_variable() noexcept {
194 }
195 inline Variable fresh_boolean_variable(const std::string& name) {
197 }
198 inline Variable fresh_real_variable() noexcept {
200 }
201 inline Variable fresh_real_variable(const std::string& name) {
203 }
204 inline Variable fresh_integer_variable() noexcept {
206 }
207 inline Variable fresh_integer_variable(const std::string& name) {
208  return fresh_variable(name, VariableType::VT_INT);
209 }
212 }
213 inline Variable fresh_uninterpreted_variable(const std::string& name) {
215 }
216 
217 // inline void printRegisteredVariableNames(std::ostream& os) {
218 // return VariablePool::getInstance().printVariableNamesToStream(os);
219 // }
220 
221 } // namespace carl
carl is the main namespace for the library.
Variable fresh_bitvector_variable() noexcept
Definition: VariablePool.h:186
Variable fresh_variable(VariableType vt) noexcept
Definition: VariablePool.h:179
VariableType
Several types of variables are supported.
Definition: Variable.h:28
Variable fresh_real_variable() noexcept
Definition: VariablePool.h:198
Variable fresh_integer_variable() noexcept
Definition: VariablePool.h:204
Variable fresh_boolean_variable() noexcept
Definition: VariablePool.h:192
Variable fresh_uninterpreted_variable() noexcept
Definition: VariablePool.h:210
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
constexpr std::size_t id() const noexcept
Retrieves the id of the variable.
Definition: Variable.h:123
constexpr VariableType type() const noexcept
Retrieves the type of the variable.
Definition: Variable.h:131
This class generates new variables and stores human-readable names for them.
Definition: VariablePool.h:27
std::mutex set_nameMutex
Mutex for calling setVariableName().
Definition: VariablePool.h:45
void set_name(Variable v, const std::string &name)
Add a name for a given Variable.
std::string get_name(Variable v, bool variableName=true) const
Get a human-readable name for the given variable.
Variable get_fresh_variable(VariableType type=VariableType::VT_REAL) noexcept
Get a variable which was not used before.
Variable get_fresh_persistent_variable(VariableType type=VariableType::VT_REAL) noexcept
Variable find_variable_with_name(const std::string &name) const noexcept
Searches in the friendly names list for a variable with the given name.
std::size_t nextID(VariableType vt) const noexcept
Definition: VariablePool.h:51
VariablePool() noexcept
Private default constructor.
friend Variable fresh_variable(VariableType vt) noexcept
Definition: VariablePool.h:179
std::size_t & nextID(VariableType vt) noexcept
Definition: VariablePool.h:47
std::mutex freshVarMutex
Mutex for calling get_fresh_variable().
Definition: VariablePool.h:40
std::string mVariablePrefix
Stores a prefix for printing variables that have no human-readable name.
Definition: VariablePool.h:69
void clear() noexcept
Clears everything already created in this pool.
Definition: VariablePool.h:109
std::map< Variable, std::string > mVariableNames
Stores human-readable names for variables that can be set via setVariableName().
Definition: VariablePool.h:64
std::array< std::size_t, static_cast< std::size_t >VariableType::TYPE_SIZE)> mNextIDs
Contains the id of the next variable to be created for each type.
Definition: VariablePool.h:35
void set_prefix(std::string prefix="_") noexcept
Sets the prefix used when printing anonymous variables.
Definition: VariablePool.h:154
std::vector< std::pair< Variable, std::string > > mPersistentVariables
Contains persistent variables that are restored after clear was called.
Definition: VariablePool.h:59
Base class that implements a singleton.
Definition: Singleton.h:24
static VariablePool & getInstance()
Returns the single instance of this class by reference.
Definition: Singleton.h:45