SMTStabilizer API
Public API documentation for SMTStabilizer
Loading...
Searching...
No Matches
options.h
Go to the documentation of this file.
1/* -*- Header -*-
2 *
3 * The Option Class
4 *
5 * Author: Fuqi Jia <jiafq@ios.ac.cn>
6 *
7 * Copyright (C) 2025 Fuqi Jia
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 */
27
28// Modified by Xiang Zhang, 2026
29// Additional changes licensed under the MIT License
30#ifndef _OPTIONS_H
31#define _OPTIONS_H
32
33#include <unordered_map>
34
35#include "asserting.h"
36
37namespace stabilizer::parser {
39 public:
40 // ENUM_LOGIC logic = UNKNOWN_LOGIC;
41 std::string logic = "ALL";
42 bool check_sat = false;
43 bool get_assertions = false;
44 bool get_assignment = false;
45 // set-info
46 std::unordered_map<std::string, std::string> info;
47 // get-info
48 std::unordered_map<std::string, std::string> get_info;
49 bool get_model = false;
50 // set-option
51 std::unordered_map<std::string, std::string> options;
52 // get-option
53 std::unordered_map<std::string, std::string> get_options;
54 bool get_proof = false;
56 bool get_unsat_core = false;
57 // get-value
58 std::unordered_map<std::string, std::string> values;
59
60 // get-objectives
61 bool get_objectives = false;
62
63 // evaluate precision
65 mpfr_prec_t evaluate_precision = 128;
66
67 // keep original representation of the division if is not divisible
69
70 // whether perserve let-binding
72
73 // whether to expand function applications (define-fun, define-fun-rec)
74 // if true (default), function calls are inlined with their definitions
75 // if false, function calls are preserved as function applications
76 bool expand_functions = true;
77
78 // whether to expand recursive functions (define-fun-rec)
79 // if true, recursive functions will be expanded like define-fun
80 // if false (default), recursive functions will not be expanded
82
83 bool rewrite = true;
84
85 public:
86 GlobalOptions() = default;
87 ~GlobalOptions() = default;
88
89 void setRewrite(bool rewrite) { this->rewrite = rewrite; }
90 bool getRewrite() const { return rewrite; }
91
92 bool setLogic(const std::string &logic_name) {
93 if (logic_name == "AUFBV" || logic_name == "QF_RDL" ||
94 logic_name == "QF_AX" || logic_name == "BV" || logic_name == "QF_FP" ||
95 logic_name == "BVFPLRA" || logic_name == "QF_UFNRA" ||
96 logic_name == "QF_ABVFPLRA" || logic_name == "ANIA" ||
97 logic_name == "LRA" || logic_name == "QF_UFLRA" ||
98 logic_name == "NIA" || logic_name == "UF" || logic_name == "UFBVDT" ||
99 logic_name == "QF_LRA" || logic_name == "QF_IDL" ||
100 logic_name == "UFDTLIA" || logic_name == "UFDT" ||
101 logic_name == "UFBVFP" || logic_name == "AUFBVDTLIA" ||
102 logic_name == "QF_S" || logic_name == "AUFBVDTNIA" ||
103 logic_name == "AUFNIRA" || logic_name == "AUFNIA" ||
104 logic_name == "QF_UFDTNIA" || logic_name == "QF_UFFPDTNIRA" ||
105 logic_name == "ABV" || logic_name == "ALIA" || logic_name == "QF_UF" ||
106 logic_name == "UFNIA" || logic_name == "UFLRA" ||
107 logic_name == "AUFFPDTNIRA" || logic_name == "FP" ||
108 logic_name == "UFFPDTNIRA" || logic_name == "QF_ANIA" ||
109 logic_name == "QF_UFDTLIA" || logic_name == "QF_BVFPLRA" ||
110 logic_name == "QF_UFBVDT" || logic_name == "QF_ABV" ||
111 logic_name == "QF_UFDT" || logic_name == "AUFBVDTNIRA" ||
112 logic_name == "QF_NIA" || logic_name == "QF_AUFNIA" ||
113 logic_name == "UFNIRA" || logic_name == "BVFP" ||
114 logic_name == "UFBVFPDTNIRA" || logic_name == "ABVFP" ||
115 logic_name == "UFDTLIRA" || logic_name == "FPLRA" ||
116 logic_name == "QF_BVFP" || logic_name == "QF_UFFP" ||
117 logic_name == "QF_FPLRA" || logic_name == "AUFBVFP" ||
118 logic_name == "AUFBVFPDTNIRA" || logic_name == "QF_AUFBV" ||
119 logic_name == "QF_NIRA" || logic_name == "QF_SLIA" ||
120 logic_name == "QF_AUFBVFP" || logic_name == "UFDTNIRA" ||
121 logic_name == "UFDTNIA" || logic_name == "QF_AUFLIA" ||
122 logic_name == "QF_UFBV" || logic_name == "AUFDTNIRA" ||
123 logic_name == "QF_ALIA" || logic_name == "QF_UFDTLIRA" ||
124 logic_name == "QF_NRA" || logic_name == "ABVFPLRA" ||
125 logic_name == "QF_BV" || logic_name == "QF_UFNIA" ||
126 logic_name == "QF_LIA" || logic_name == "UFBVDTLIA" ||
127 logic_name == "AUFDTLIRA" || logic_name == "UFIDL" ||
128 logic_name == "LIA" || logic_name == "UFBVDTNIA" ||
129 logic_name == "QF_ABVFP" || logic_name == "QF_LIRA" ||
130 logic_name == "UFBV" || logic_name == "QF_UFIDL" ||
131 logic_name == "AUFLIA" || logic_name == "UFBVDTNIRA" ||
132 logic_name == "AUFLIRA" || logic_name == "UFLIA" ||
133 logic_name == "AUFDTLIA" || logic_name == "QF_UFLIA" ||
134 logic_name == "UFBVLIA" || logic_name == "QF_SNIA" ||
135 logic_name == "QF_DT" || logic_name == "NRA" || logic_name == "ALL") {
136 logic = logic_name;
137 return true;
138 }
139 else {
140 // logic = "UNKNOWN_LOGIC";
141 logic = "ALL";
142 return false;
143 }
144 }
145
146 void setOption(const std::string &key, const std::string &value) {
147 options[key] = value;
148 if (key == "keep_let") {
149 setKeepLet(value == "true");
150 }
151 else if (key == "keep_division") {
152 setKeepDivision(value == "true");
153 }
154 else if (key == "precision") {
155 setEvaluatePrecision((size_t)(std::stoi(value)));
156 }
157 else if (key == "float_evaluate") {
158 setEvaluateUseFloating(value == "true");
159 }
160 else if (key == "expand_functions") {
161 setExpandFunctions(value == "true");
162 }
163 else if (key == "expand_recursive_functions") {
164 setExpandRecursiveFunctions(value == "true");
165 }
166 }
167
168 void setInfo(const std::string &key, const std::string &value) {
169 info[key] = value;
170 }
171
172 std::string getLogic() const { return logic; }
173
174 void getValue(const std::string &key, const std::string &value) {
175 values[key] = value;
176 }
177
178 void getInfo(const std::string &key, const std::string &value) {
179 get_info[key] = value;
180 }
181
182 void getOption(const std::string &key, const std::string &value) {
183 get_options[key] = value;
184 }
185
186 // logic checking
187 bool isIntTheory() const {
188 return logic.find("I") != std::string::npos &&
189 logic.find("R") == std::string::npos;
190 }
191 bool isRealTheory() const { return logic.find("R") != std::string::npos; }
192 bool isIntRealTheory() const {
193 return logic.find("I") != std::string::npos &&
194 logic.find("R") != std::string::npos;
195 }
196
197 void setEvaluatePrecision(mpfr_prec_t precision) {
198 evaluate_precision = precision;
199 }
200
201 mpfr_prec_t getEvaluatePrecision() const { return evaluate_precision; }
202
203 void setEvaluateUseFloating(bool use_floating) {
204 evaluate_use_floating = use_floating;
205 }
206
208
210 void setKeepLet(bool keep) { parsing_preserve_let = keep; }
212 bool getKeepLet() const { return parsing_preserve_let; }
213
214 void setExpandFunctions(bool expand) { expand_functions = expand; }
215 bool getExpandFunctions() const { return expand_functions; }
216
217 void setExpandRecursiveFunctions(bool expand) {
219 }
223
234 std::string toString() const {
235 std::string result;
236 result +=
237 "=================================================================\n";
238 result += " stabilizer::parser Configuration Report\n";
239 result +=
240 "=================================================================\n\n";
241
242 // Logic setting
243 result += "1. Logic\n";
244 result += " Option: logic\n";
245 result += " Default: UNKNOWN_LOGIC\n";
246 result += " Current: " + logic + "\n";
247 result +=
248 " Description: The SMT-LIB2 logic to use for parsing and "
249 "reasoning.\n";
250 result +=
251 " Determines which theories and quantifiers are "
252 "allowed.\n\n";
253
254 // Evaluation precision
255 result += "2. Evaluation Precision\n";
256 result +=
257 " Option: precision (set via setOption or setEvaluatePrecision)\n";
258 result += " Default: 128\n";
259 result += " Current: " + std::to_string(evaluate_precision) + "\n";
260 result +=
261 " Description: The precision (in bits) for MPFR floating-point "
262 "evaluation.\n";
263 result +=
264 " Higher values provide more accurate results but "
265 "slower computation.\n\n";
266
267 // Floating point evaluation
268 result += "3. Floating-Point Evaluation Mode\n";
269 result +=
270 " Option: float_evaluate (set via setOption or "
271 "setEvaluateUseFloating)\n";
272 result += " Default: true\n";
273 result +=
274 " Current: " + std::string(evaluate_use_floating ? "true" : "false") +
275 "\n";
276 result +=
277 " Description: When enabled, uses floating-point arithmetic "
278 "for evaluation.\n";
279 result +=
280 " When disabled, uses exact rational arithmetic "
281 "where possible.\n\n";
282
283 // Keep division
284 result += "4. Keep Division If Not Divisible\n";
285 result +=
286 " Option: keep_division (set via setOption or setKeepDivision)\n";
287 result += " Default: true\n";
288 result += " Current: " +
289 std::string(keep_division_if_not_divisible ? "true" : "false") +
290 "\n";
291 result +=
292 " Description: When enabled, preserves division operations in "
293 "their original form\n";
294 result +=
295 " if the division is not exact. When disabled, "
296 "always computes the result.\n\n";
297
298 // Preserve let bindings
299 result += "5. Preserve Let Bindings\n";
300 result += " Option: keep_let (set via setOption or setKeepLet)\n";
301 result += " Default: true\n";
302 result +=
303 " Current: " + std::string(parsing_preserve_let ? "true" : "false") +
304 "\n";
305 result +=
306 " Description: When enabled, preserves let-binding structures "
307 "during parsing.\n";
308 result +=
309 " When disabled, automatically expands "
310 "let-bindings inline.\n\n";
311
312 // Expand functions
313 result += "6. Expand Function Applications\n";
314 result +=
315 " Option: expand_functions (set via setOption or "
316 "setExpandFunctions)\n";
317 result += " Default: true\n";
318 result +=
319 " Current: " + std::string(expand_functions ? "true" : "false") +
320 "\n";
321 result +=
322 " Description: When enabled (default), function calls "
323 "(define-fun) are inlined with\n";
324 result +=
325 " their definitions. When disabled, function "
326 "applications are preserved\n";
327 result +=
328 " as-is, keeping the function call structure in "
329 "the AST.\n\n";
330
331 // Expand recursive functions
332 result += "7. Expand Recursive Functions\n";
333 result +=
334 " Option: expand_recursive_functions (set via setOption or "
335 "setExpandRecursiveFunctions)\n";
336 result += " Default: false\n";
337 result += " Current: " +
338 std::string(expand_recursive_functions ? "true" : "false") + "\n";
339 result += " Status: NOT CURRENTLY SUPPORTED\n";
340 result +=
341 " Description: When enabled, recursive functions "
342 "(define-fun-rec) would be expanded\n";
343 result +=
344 " like regular function definitions. This feature "
345 "is planned for future\n";
346 result +=
347 " implementation using a 'this' placeholder "
348 "mechanism to handle recursive\n";
349 result +=
350 " self-references during function body parsing "
351 "and expansion.\n\n";
352
353 // Command flags
354 result += "8. Command Flags\n";
355 result +=
356 " check_sat: " + std::string(check_sat ? "true" : "false") + "\n";
357 result +=
358 " get_assertions: " + std::string(get_assertions ? "true" : "false") +
359 "\n";
360 result +=
361 " get_assignment: " + std::string(get_assignment ? "true" : "false") +
362 "\n";
363 result +=
364 " get_model: " + std::string(get_model ? "true" : "false") + "\n";
365 result +=
366 " get_proof: " + std::string(get_proof ? "true" : "false") + "\n";
367 result += " get_unsat_assumptions: " +
368 std::string(get_unsat_assumptions ? "true" : "false") + "\n";
369 result +=
370 " get_unsat_core: " + std::string(get_unsat_core ? "true" : "false") +
371 "\n";
372 result +=
373 " get_objectives: " + std::string(get_objectives ? "true" : "false") +
374 "\n";
375 result +=
376 " Description: Flags indicating which SMT-LIB2 commands have "
377 "been encountered.\n\n";
378
379 // Set-info
380 if (!info.empty()) {
381 result += "8. Set-Info Attributes\n";
382 for (const auto &kv : info) {
383 result += " " + kv.first + " = " + kv.second + "\n";
384 }
385 result += "\n";
386 }
387
388 // Set-option
389 if (!options.empty()) {
390 result += "9. Set-Option Values\n";
391 for (const auto &kv : options) {
392 result += " " + kv.first + " = " + kv.second + "\n";
393 }
394 result += "\n";
395 }
396
397 // Get-info
398 if (!get_info.empty()) {
399 result += "10. Get-Info Queries\n";
400 for (const auto &kv : get_info) {
401 result += " " + kv.first + " = " + kv.second + "\n";
402 }
403 result += "\n";
404 }
405
406 // Get-option
407 if (!get_options.empty()) {
408 result += "11. Get-Option Queries\n";
409 for (const auto &kv : get_options) {
410 result += " " + kv.first + " = " + kv.second + "\n";
411 }
412 result += "\n";
413 }
414
415 // Get-value
416 if (!values.empty()) {
417 result += "12. Get-Value Queries\n";
418 for (const auto &kv : values) {
419 result += " " + kv.first + " = " + kv.second + "\n";
420 }
421 result += "\n";
422 }
423
424 result +=
425 "=================================================================\n";
426 return result;
427 }
428};
429} // namespace stabilizer::parser
430#endif // _OPTIONS_H
std::unordered_map< std::string, std::string > info
Definition options.h:46
std::unordered_map< std::string, std::string > get_info
Definition options.h:48
std::unordered_map< std::string, std::string > values
Definition options.h:58
void getValue(const std::string &key, const std::string &value)
Definition options.h:174
void setExpandFunctions(bool expand)
Definition options.h:214
void setOption(const std::string &key, const std::string &value)
Definition options.h:146
mpfr_prec_t getEvaluatePrecision() const
Definition options.h:201
void setExpandRecursiveFunctions(bool expand)
Definition options.h:217
bool getExpandRecursiveFunctions() const
Definition options.h:220
bool setLogic(const std::string &logic_name)
Definition options.h:92
void getOption(const std::string &key, const std::string &value)
Definition options.h:182
void setInfo(const std::string &key, const std::string &value)
Definition options.h:168
std::string toString() const
Generate a detailed configuration report.
Definition options.h:234
std::unordered_map< std::string, std::string > options
Definition options.h:51
void setKeepDivision(bool keep)
Definition options.h:209
std::string getLogic() const
Definition options.h:172
void setRewrite(bool rewrite)
Definition options.h:89
void setEvaluateUseFloating(bool use_floating)
Definition options.h:203
void setEvaluatePrecision(mpfr_prec_t precision)
Definition options.h:197
void getInfo(const std::string &key, const std::string &value)
Definition options.h:178
std::unordered_map< std::string, std::string > get_options
Definition options.h:53