1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Tim King, Morgan Deters, Paul Meng |
4 |
|
* |
5 |
|
* This file is part of the cvc5 project. |
6 |
|
* |
7 |
|
* Copyright (c) 2009-2021 by the authors listed in the file AUTHORS |
8 |
|
* in the top-level source directory and their institutional affiliations. |
9 |
|
* All rights reserved. See the file COPYING in the top-level source |
10 |
|
* directory for licensing information. |
11 |
|
* **************************************************************************** |
12 |
|
* |
13 |
|
* Global (command-line, set-option, ...) parameters for SMT. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "cvc5_public.h" |
17 |
|
|
18 |
|
#ifndef CVC5__OPTIONS__OPTIONS_H |
19 |
|
#define CVC5__OPTIONS__OPTIONS_H |
20 |
|
|
21 |
|
#include <iosfwd> |
22 |
|
#include <memory> |
23 |
|
#include <string> |
24 |
|
#include <vector> |
25 |
|
|
26 |
|
#include "base/listener.h" |
27 |
|
#include "cvc5_export.h" |
28 |
|
#include "options/language.h" |
29 |
|
#include "options/printer_modes.h" |
30 |
|
|
31 |
|
namespace cvc5 { |
32 |
|
|
33 |
|
namespace api { |
34 |
|
class Solver; |
35 |
|
} |
36 |
|
namespace options { |
37 |
|
struct OptionsHolder; |
38 |
|
class OptionsHandler; |
39 |
|
// clang-format off |
40 |
|
struct HolderARITH; |
41 |
|
struct HolderARRAYS; |
42 |
|
struct HolderBASE; |
43 |
|
struct HolderBOOLEANS; |
44 |
|
struct HolderBUILTIN; |
45 |
|
struct HolderBV; |
46 |
|
struct HolderDATATYPES; |
47 |
|
struct HolderDECISION; |
48 |
|
struct HolderEXPR; |
49 |
|
struct HolderFP; |
50 |
|
struct HolderDRIVER; |
51 |
|
struct HolderPARSER; |
52 |
|
struct HolderPRINTER; |
53 |
|
struct HolderPROOF; |
54 |
|
struct HolderPROP; |
55 |
|
struct HolderQUANTIFIERS; |
56 |
|
struct HolderRESMAN; |
57 |
|
struct HolderSEP; |
58 |
|
struct HolderSETS; |
59 |
|
struct HolderSMT; |
60 |
|
struct HolderSTRINGS; |
61 |
|
struct HolderTHEORY; |
62 |
|
struct HolderUF; |
63 |
|
// clang-format on |
64 |
|
} // namespace options |
65 |
|
|
66 |
|
class OptionsListener; |
67 |
|
|
68 |
|
class CVC5_EXPORT Options |
69 |
|
{ |
70 |
|
friend api::Solver; |
71 |
|
|
72 |
|
/** The handler for the options of the theory. */ |
73 |
|
options::OptionsHandler* d_handler; |
74 |
|
|
75 |
|
// clang-format off |
76 |
|
std::unique_ptr<options::HolderARITH> d_arith; |
77 |
|
std::unique_ptr<options::HolderARRAYS> d_arrays; |
78 |
|
std::unique_ptr<options::HolderBASE> d_base; |
79 |
|
std::unique_ptr<options::HolderBOOLEANS> d_booleans; |
80 |
|
std::unique_ptr<options::HolderBUILTIN> d_builtin; |
81 |
|
std::unique_ptr<options::HolderBV> d_bv; |
82 |
|
std::unique_ptr<options::HolderDATATYPES> d_datatypes; |
83 |
|
std::unique_ptr<options::HolderDECISION> d_decision; |
84 |
|
std::unique_ptr<options::HolderEXPR> d_expr; |
85 |
|
std::unique_ptr<options::HolderFP> d_fp; |
86 |
|
std::unique_ptr<options::HolderDRIVER> d_driver; |
87 |
|
std::unique_ptr<options::HolderPARSER> d_parser; |
88 |
|
std::unique_ptr<options::HolderPRINTER> d_printer; |
89 |
|
std::unique_ptr<options::HolderPROOF> d_proof; |
90 |
|
std::unique_ptr<options::HolderPROP> d_prop; |
91 |
|
std::unique_ptr<options::HolderQUANTIFIERS> d_quantifiers; |
92 |
|
std::unique_ptr<options::HolderRESMAN> d_resman; |
93 |
|
std::unique_ptr<options::HolderSEP> d_sep; |
94 |
|
std::unique_ptr<options::HolderSETS> d_sets; |
95 |
|
std::unique_ptr<options::HolderSMT> d_smt; |
96 |
|
std::unique_ptr<options::HolderSTRINGS> d_strings; |
97 |
|
std::unique_ptr<options::HolderTHEORY> d_theory; |
98 |
|
std::unique_ptr<options::HolderUF> d_uf; |
99 |
|
// clang-format on |
100 |
|
|
101 |
|
/** The current Options in effect */ |
102 |
|
static thread_local Options* s_current; |
103 |
|
|
104 |
|
/** Low-level assignment function for options */ |
105 |
|
template <class T> |
106 |
|
void assign(T, std::string option, std::string value); |
107 |
|
/** Low-level assignment function for bool-valued options */ |
108 |
|
template <class T> |
109 |
|
void assignBool(T, std::string option, bool value); |
110 |
|
|
111 |
|
friend class options::OptionsHandler; |
112 |
|
|
113 |
|
/** |
114 |
|
* Options cannot be copied as they are given an explicit list of |
115 |
|
* Listeners to respond to. |
116 |
|
*/ |
117 |
|
Options(const Options& options) = delete; |
118 |
|
|
119 |
|
/** |
120 |
|
* Options cannot be assigned as they are given an explicit list of |
121 |
|
* Listeners to respond to. |
122 |
|
*/ |
123 |
|
Options& operator=(const Options& options) = delete; |
124 |
|
|
125 |
|
static std::string formatThreadOptionException(const std::string& option); |
126 |
|
|
127 |
|
public: |
128 |
|
class OptionsScope |
129 |
|
{ |
130 |
|
private: |
131 |
|
Options* d_oldOptions; |
132 |
|
public: |
133 |
154710 |
OptionsScope(Options* newOptions) : |
134 |
315632514 |
d_oldOptions(Options::s_current) |
135 |
|
{ |
136 |
154710 |
Options::s_current = newOptions; |
137 |
154710 |
} |
138 |
309420 |
~OptionsScope(){ |
139 |
154710 |
Options::s_current = d_oldOptions; |
140 |
154710 |
} |
141 |
|
}; |
142 |
|
|
143 |
|
/** Return true if current Options are null */ |
144 |
104310 |
static inline bool isCurrentNull() { |
145 |
104310 |
return s_current == NULL; |
146 |
|
} |
147 |
|
|
148 |
|
/** Get the current Options in effect */ |
149 |
314909364 |
static inline Options& current() { |
150 |
314909364 |
return *s_current; |
151 |
|
} |
152 |
|
|
153 |
|
Options(OptionsListener* ol = nullptr); |
154 |
|
~Options(); |
155 |
|
|
156 |
|
// clang-format off |
157 |
|
const options::HolderARITH& arith() const; |
158 |
|
options::HolderARITH& arith(); |
159 |
|
const options::HolderARRAYS& arrays() const; |
160 |
|
options::HolderARRAYS& arrays(); |
161 |
|
const options::HolderBASE& base() const; |
162 |
|
options::HolderBASE& base(); |
163 |
|
const options::HolderBOOLEANS& booleans() const; |
164 |
|
options::HolderBOOLEANS& booleans(); |
165 |
|
const options::HolderBUILTIN& builtin() const; |
166 |
|
options::HolderBUILTIN& builtin(); |
167 |
|
const options::HolderBV& bv() const; |
168 |
|
options::HolderBV& bv(); |
169 |
|
const options::HolderDATATYPES& datatypes() const; |
170 |
|
options::HolderDATATYPES& datatypes(); |
171 |
|
const options::HolderDECISION& decision() const; |
172 |
|
options::HolderDECISION& decision(); |
173 |
|
const options::HolderEXPR& expr() const; |
174 |
|
options::HolderEXPR& expr(); |
175 |
|
const options::HolderFP& fp() const; |
176 |
|
options::HolderFP& fp(); |
177 |
|
const options::HolderDRIVER& driver() const; |
178 |
|
options::HolderDRIVER& driver(); |
179 |
|
const options::HolderPARSER& parser() const; |
180 |
|
options::HolderPARSER& parser(); |
181 |
|
const options::HolderPRINTER& printer() const; |
182 |
|
options::HolderPRINTER& printer(); |
183 |
|
const options::HolderPROOF& proof() const; |
184 |
|
options::HolderPROOF& proof(); |
185 |
|
const options::HolderPROP& prop() const; |
186 |
|
options::HolderPROP& prop(); |
187 |
|
const options::HolderQUANTIFIERS& quantifiers() const; |
188 |
|
options::HolderQUANTIFIERS& quantifiers(); |
189 |
|
const options::HolderRESMAN& resman() const; |
190 |
|
options::HolderRESMAN& resman(); |
191 |
|
const options::HolderSEP& sep() const; |
192 |
|
options::HolderSEP& sep(); |
193 |
|
const options::HolderSETS& sets() const; |
194 |
|
options::HolderSETS& sets(); |
195 |
|
const options::HolderSMT& smt() const; |
196 |
|
options::HolderSMT& smt(); |
197 |
|
const options::HolderSTRINGS& strings() const; |
198 |
|
options::HolderSTRINGS& strings(); |
199 |
|
const options::HolderTHEORY& theory() const; |
200 |
|
options::HolderTHEORY& theory(); |
201 |
|
const options::HolderUF& uf() const; |
202 |
|
options::HolderUF& uf(); |
203 |
|
// clang-format on |
204 |
|
|
205 |
|
/** |
206 |
|
* Copies the value of the options stored in OptionsHolder into the current |
207 |
|
* Options object. |
208 |
|
* This does not copy the listeners in the Options object. |
209 |
|
*/ |
210 |
|
void copyValues(const Options& options); |
211 |
|
|
212 |
|
/** |
213 |
|
* Set the value of the given option. Uses `ref()`, which causes a |
214 |
|
* compile-time error if the given option is read-only. |
215 |
|
*/ |
216 |
|
template <class T> |
217 |
204979 |
void set(T t, const typename T::type& val) { |
218 |
204979 |
ref(t) = val; |
219 |
204979 |
} |
220 |
|
|
221 |
|
/** |
222 |
|
* Set the default value of the given option. Is equivalent to calling `set()` |
223 |
|
* if `wasSetByUser()` returns false. Uses `ref()`, which causes a compile-time |
224 |
|
* error if the given option is read-only. |
225 |
|
*/ |
226 |
|
template <class T> |
227 |
14 |
void setDefault(T t, const typename T::type& val) |
228 |
|
{ |
229 |
14 |
if (!wasSetByUser(t)) |
230 |
|
{ |
231 |
14 |
ref(t) = val; |
232 |
|
} |
233 |
14 |
} |
234 |
|
|
235 |
|
/** |
236 |
|
* Get a non-const reference to the value of the given option. Causes a |
237 |
|
* compile-time error if the given option is read-only. Writeable options |
238 |
|
* specialize this template with a real implementation. |
239 |
|
*/ |
240 |
|
template <class T> |
241 |
|
typename T::type& ref(T) { |
242 |
|
// Flag a compile-time error. |
243 |
|
T::you_are_trying_to_get_nonconst_access_to_a_read_only_option; |
244 |
|
// Ensure the compiler does not complain about the return value. |
245 |
|
return *static_cast<typename T::type*>(nullptr); |
246 |
|
} |
247 |
|
|
248 |
|
/** |
249 |
|
* Set the value of the given option by key. |
250 |
|
* |
251 |
|
* Throws OptionException or ModalException on failures. |
252 |
|
*/ |
253 |
|
void setOption(const std::string& key, const std::string& optionarg); |
254 |
|
|
255 |
|
/** Get the value of the given option. Const access only. */ |
256 |
|
template <class T> |
257 |
|
const typename T::type& operator[](T) const; |
258 |
|
|
259 |
|
/** |
260 |
|
* Gets the value of the given option by key and returns value as a string. |
261 |
|
* |
262 |
|
* Throws OptionException on failures, such as key not being the name of an |
263 |
|
* option. |
264 |
|
*/ |
265 |
|
std::string getOption(const std::string& key) const; |
266 |
|
|
267 |
|
// Get accessor functions. |
268 |
|
InputLanguage getInputLanguage() const; |
269 |
|
options::InstFormatMode getInstFormatMode() const; |
270 |
|
OutputLanguage getOutputLanguage() const; |
271 |
|
bool getUfHo() const; |
272 |
|
bool getDumpInstantiations() const; |
273 |
|
bool getDumpModels() const; |
274 |
|
bool getDumpProofs() const; |
275 |
|
bool getDumpUnsatCores() const; |
276 |
|
bool getEarlyExit() const; |
277 |
|
bool getFilesystemAccess() const; |
278 |
|
bool getForceNoLimitCpuWhileDump() const; |
279 |
|
bool getHelp() const; |
280 |
|
bool getIncrementalSolving() const; |
281 |
|
bool getInteractive() const; |
282 |
|
bool getInteractivePrompt() const; |
283 |
|
bool getLanguageHelp() const; |
284 |
|
bool getMemoryMap() const; |
285 |
|
bool getParseOnly() const; |
286 |
|
bool getProduceModels() const; |
287 |
|
bool getSegvSpin() const; |
288 |
|
bool getSemanticChecks() const; |
289 |
|
bool getStatistics() const; |
290 |
|
bool getStatsEveryQuery() const; |
291 |
|
bool getStrictParsing() const; |
292 |
|
int getTearDownIncremental() const; |
293 |
|
uint64_t getCumulativeTimeLimit() const; |
294 |
|
bool getVersion() const; |
295 |
|
const std::string& getForceLogicString() const; |
296 |
|
int getVerbosity() const; |
297 |
|
std::istream* getIn() const; |
298 |
|
std::ostream* getErr(); |
299 |
|
std::ostream* getOut(); |
300 |
|
std::ostream* getOutConst() const; // TODO: Remove this. |
301 |
|
std::string getBinaryName() const; |
302 |
|
|
303 |
|
// TODO: Document these. |
304 |
|
void setInputLanguage(InputLanguage); |
305 |
|
void setInteractive(bool); |
306 |
|
void setOut(std::ostream*); |
307 |
|
void setOutputLanguage(OutputLanguage); |
308 |
|
|
309 |
|
bool wasSetByUserEarlyExit() const; |
310 |
|
bool wasSetByUserForceLogicString() const; |
311 |
|
bool wasSetByUserIncrementalSolving() const; |
312 |
|
bool wasSetByUserInteractive() const; |
313 |
|
|
314 |
|
// Static accessor functions. |
315 |
|
// TODO: Document these. |
316 |
|
static std::ostream* currentGetOut(); |
317 |
|
|
318 |
|
/** |
319 |
|
* Returns true iff the value of the given option was set |
320 |
|
* by the user via a command-line option or SmtEngine::setOption(). |
321 |
|
* (Options::set() is low-level and doesn't count.) Returns false |
322 |
|
* otherwise. |
323 |
|
*/ |
324 |
|
template <class T> |
325 |
|
bool wasSetByUser(T) const; |
326 |
|
|
327 |
|
/** |
328 |
|
* Get a description of the command-line flags accepted by |
329 |
|
* parseOptions. The returned string will be escaped so that it is |
330 |
|
* suitable as an argument to printf. */ |
331 |
|
std::string getDescription() const; |
332 |
|
|
333 |
|
/** |
334 |
|
* Print overall command-line option usage message, prefixed by |
335 |
|
* "msg"---which could be an error message causing the usage |
336 |
|
* output in the first place, e.g. "no such option --foo" |
337 |
|
*/ |
338 |
|
static void printUsage(const std::string msg, std::ostream& out); |
339 |
|
|
340 |
|
/** |
341 |
|
* Print command-line option usage message for only the most-commonly |
342 |
|
* used options. The message is prefixed by "msg"---which could be |
343 |
|
* an error message causing the usage output in the first place, e.g. |
344 |
|
* "no such option --foo" |
345 |
|
*/ |
346 |
|
static void printShortUsage(const std::string msg, std::ostream& out); |
347 |
|
|
348 |
|
/** Print help for the --lang command line option */ |
349 |
|
static void printLanguageHelp(std::ostream& out); |
350 |
|
|
351 |
|
/** |
352 |
|
* Initialize the Options object options based on the given |
353 |
|
* command-line arguments given in argc and argv. The return value |
354 |
|
* is what's left of the command line (that is, the non-option |
355 |
|
* arguments). |
356 |
|
* |
357 |
|
* This function uses getopt_long() and is not thread safe. |
358 |
|
* |
359 |
|
* Throws OptionException on failures. |
360 |
|
* |
361 |
|
* Preconditions: options and argv must be non-null. |
362 |
|
*/ |
363 |
|
static std::vector<std::string> parseOptions(Options* options, |
364 |
|
int argc, |
365 |
|
char* argv[]); |
366 |
|
|
367 |
|
/** |
368 |
|
* Get the setting for all options. |
369 |
|
*/ |
370 |
|
std::vector<std::vector<std::string> > getOptions() const; |
371 |
|
|
372 |
|
/** Set the generic listener associated with this class to ol */ |
373 |
|
void setListener(OptionsListener* ol); |
374 |
|
|
375 |
|
/** Sends a std::flush to getErr(). */ |
376 |
|
void flushErr(); |
377 |
|
|
378 |
|
/** Sends a std::flush to getOut(). */ |
379 |
|
void flushOut(); |
380 |
|
|
381 |
|
private: |
382 |
|
/** Pointer to the options listener, if one exists */ |
383 |
|
OptionsListener* d_olisten; |
384 |
|
/** |
385 |
|
* Helper method for setOption, updates this object for setting the given |
386 |
|
* option. |
387 |
|
*/ |
388 |
|
void setOptionInternal(const std::string& key, const std::string& optionarg); |
389 |
|
/** |
390 |
|
* Internal procedure for implementing the parseOptions function. |
391 |
|
* Initializes the options object based on the given command-line |
392 |
|
* arguments. The command line arguments are stored in argc/argv. |
393 |
|
* Nonoptions are stored into nonoptions. |
394 |
|
* |
395 |
|
* This is not thread safe. |
396 |
|
* |
397 |
|
* Throws OptionException on failures. |
398 |
|
* |
399 |
|
* Preconditions: options, extender and nonoptions are non-null. |
400 |
|
*/ |
401 |
|
void parseOptionsRecursive(int argc, |
402 |
|
char* argv[], |
403 |
|
std::vector<std::string>* nonoptions); |
404 |
|
}; /* class Options */ |
405 |
|
|
406 |
|
} // namespace cvc5 |
407 |
|
|
408 |
|
#endif /* CVC5__OPTIONS__OPTIONS_H */ |