CBMC
solver_factory.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Solver Factory
4 
5 Author: Daniel Kroening, Peter Schrammel
6 
7 \*******************************************************************/
8 
11 
12 #include "solver_factory.h"
13 
14 #include <util/cmdline.h>
15 #include <util/exception_utils.h>
16 #include <util/exit_codes.h>
17 #include <util/message.h>
18 #include <util/options.h>
19 #include <util/unicode.h>
20 #include <util/version.h>
21 
24 #include <solvers/prop/prop.h>
27 #include <solvers/sat/dimacs_cnf.h>
29 #include <solvers/sat/satcheck.h>
34 
35 #include <iostream>
36 
38  const optionst &_options,
39  const namespacet &_ns,
40  message_handlert &_message_handler,
41  bool _output_xml_in_refinement)
42  : options(_options),
43  ns(_ns),
44  message_handler(_message_handler),
45  output_xml_in_refinement(_output_xml_in_refinement)
46 {
47 }
48 
49 solver_factoryt::solvert::solvert(std::unique_ptr<decision_proceduret> p)
50  : decision_procedure_ptr(std::move(p))
51 {
52 }
53 
55  std::unique_ptr<decision_proceduret> p1,
56  std::unique_ptr<propt> p2)
57  : prop_ptr(std::move(p2)), decision_procedure_ptr(std::move(p1))
58 {
59 }
60 
62  std::unique_ptr<decision_proceduret> p1,
63  std::unique_ptr<std::ofstream> p2)
64  : ofstream_ptr(std::move(p2)), decision_procedure_ptr(std::move(p1))
65 {
66 }
67 
69 {
70  PRECONDITION(decision_procedure_ptr != nullptr);
71  return *decision_procedure_ptr;
72 }
73 
76 {
77  PRECONDITION(decision_procedure_ptr != nullptr);
79  dynamic_cast<stack_decision_proceduret *>(&*decision_procedure_ptr);
80  INVARIANT(solver != nullptr, "stack decision procedure required");
81  return *solver;
82 }
83 
85  decision_proceduret &decision_procedure)
86 {
87  const int timeout_seconds =
88  options.get_signed_int_option("solver-time-limit");
89 
90  if(timeout_seconds > 0)
91  {
93  dynamic_cast<solver_resource_limitst *>(&decision_procedure);
94  if(solver == nullptr)
95  {
97  log.warning() << "cannot set solver time limit on "
98  << decision_procedure.decision_procedure_text()
99  << messaget::eom;
100  return;
101  }
102 
103  solver->set_time_limit_seconds(timeout_seconds);
104  }
105 }
106 
108  std::unique_ptr<decision_proceduret> p)
109 {
110  decision_procedure_ptr = std::move(p);
111 }
112 
113 void solver_factoryt::solvert::set_prop(std::unique_ptr<propt> p)
114 {
115  prop_ptr = std::move(p);
116 }
117 
118 void solver_factoryt::solvert::set_ofstream(std::unique_ptr<std::ofstream> p)
119 {
120  ofstream_ptr = std::move(p);
121 }
122 
123 std::unique_ptr<solver_factoryt::solvert> solver_factoryt::get_solver()
124 {
125  if(options.get_bool_option("dimacs"))
126  return get_dimacs();
127  if(options.is_set("external-sat-solver"))
128  return get_external_sat();
129  if(
130  options.get_bool_option("refine") &&
131  !options.get_bool_option("refine-strings"))
132  {
133  return get_bv_refinement();
134  }
135  else if(options.get_bool_option("refine-strings"))
136  return get_string_refinement();
137  const auto incremental_smt2_solver =
138  options.get_option("incremental-smt2-solver");
139  if(!incremental_smt2_solver.empty())
140  return get_incremental_smt2(incremental_smt2_solver);
141  if(options.get_bool_option("smt2"))
142  return get_smt2(get_smt2_solver_type());
143  return get_default();
144 }
145 
149 {
150  // we shouldn't get here if this option isn't set
152 
154 
155  if(options.get_bool_option("bitwuzla"))
157  else if(options.get_bool_option("boolector"))
159  else if(options.get_bool_option("cprover-smt2"))
161  else if(options.get_bool_option("mathsat"))
163  else if(options.get_bool_option("cvc3"))
165  else if(options.get_bool_option("cvc4"))
167  else if(options.get_bool_option("cvc5"))
169  else if(options.get_bool_option("yices"))
171  else if(options.get_bool_option("z3"))
173  else if(options.get_bool_option("generic"))
175 
176  return s;
177 }
178 
182  const std::string &solver)
183 {
185  log.warning() << "The specified solver, '" << solver
186  << "', is not available. "
187  << "The default solver will be used instead." << messaget::eom;
188 }
189 
190 template <typename SatcheckT>
191 static std::unique_ptr<SatcheckT>
193 {
194  auto satcheck = std::make_unique<SatcheckT>(message_handler);
195  if(options.is_set("write-solver-stats-to"))
196  {
197  if(
198  auto hardness_collector = dynamic_cast<hardness_collectort *>(&*satcheck))
199  {
200  std::unique_ptr<solver_hardnesst> solver_hardness =
201  std::make_unique<solver_hardnesst>();
202  solver_hardness->set_outfile(options.get_option("write-solver-stats-to"));
203  hardness_collector->solver_hardness = std::move(solver_hardness);
204  }
205  else
206  {
208  log.warning()
209  << "Configured solver does not support --write-solver-stats-to. "
210  << "Solver stats will not be written." << messaget::eom;
211  }
212  }
213  return satcheck;
214 }
215 
216 static std::unique_ptr<propt>
218 {
219  const bool no_simplifier = options.get_bool_option("beautify") ||
220  !options.get_bool_option("sat-preprocessor") ||
221  options.get_bool_option("refine-arithmetic") ||
222  options.get_bool_option("refine-strings");
223 
224  if(options.is_set("sat-solver"))
225  {
226  const std::string &solver_option = options.get_option("sat-solver");
227  if(solver_option == "zchaff")
228  {
229 #if defined SATCHECK_ZCHAFF
230  return make_satcheck_prop<satcheck_zchafft>(message_handler, options);
231 #else
233 #endif
234  }
235  else if(solver_option == "booleforce")
236  {
237 #if defined SATCHECK_BOOLERFORCE
238  return make_satcheck_prop<satcheck_booleforcet>(message_handler, options);
239 #else
240  emit_solver_warning(message_handler, "booleforce");
241 #endif
242  }
243  else if(solver_option == "minisat1")
244  {
245 #if defined SATCHECK_MINISAT1
246  return make_satcheck_prop<satcheck_minisat1t>(message_handler, options);
247 #else
249 #endif
250  }
251  else if(solver_option == "minisat2")
252  {
253 #if defined SATCHECK_MINISAT2
254  if(no_simplifier)
255  {
256  // simplifier won't work with beautification
257  return make_satcheck_prop<satcheck_minisat_no_simplifiert>(
259  }
260  else // with simplifier
261  {
262  return make_satcheck_prop<satcheck_minisat_simplifiert>(
264  }
265 #else
267 #endif
268  }
269  else if(solver_option == "ipasir")
270  {
271 #if defined SATCHECK_IPASIR
272  return make_satcheck_prop<satcheck_ipasirt>(message_handler, options);
273 #else
275 #endif
276  }
277  else if(solver_option == "picosat")
278  {
279 #if defined SATCHECK_PICOSAT
280  return make_satcheck_prop<satcheck_picosatt>(message_handler, options);
281 #else
283 #endif
284  }
285  else if(solver_option == "lingeling")
286  {
287 #if defined SATCHECK_LINGELING
288  return make_satcheck_prop<satcheck_lingelingt>(message_handler, options);
289 #else
290  emit_solver_warning(message_handler, "lingeling");
291 #endif
292  }
293  else if(solver_option == "glucose")
294  {
295 #if defined SATCHECK_GLUCOSE
296  if(no_simplifier)
297  {
298  // simplifier won't work with beautification
299  return make_satcheck_prop<satcheck_glucose_no_simplifiert>(
301  }
302  else // with simplifier
303  {
304  return make_satcheck_prop<satcheck_glucose_simplifiert>(
306  }
307 #else
309 #endif
310  }
311  else if(solver_option == "cadical")
312  {
313 #if defined SATCHECK_CADICAL
314  return make_satcheck_prop<satcheck_cadicalt>(message_handler, options);
315 #else
317 #endif
318  }
319  else
320  {
322  log.error() << "unknown solver '" << solver_option << "'"
323  << messaget::eom;
325  }
326  }
327 
328  // default solver
329  if(no_simplifier)
330  {
331  // simplifier won't work with beautification
332  return make_satcheck_prop<satcheck_no_simplifiert>(
334  }
335  else // with simplifier
336  {
337  return make_satcheck_prop<satcheckt>(message_handler, options);
338  }
339 }
340 
341 std::unique_ptr<solver_factoryt::solvert> solver_factoryt::get_default()
342 {
343  auto sat_solver = get_sat_solver(message_handler, options);
344 
345  bool get_array_constraints =
346  options.get_bool_option("show-array-constraints");
347  auto bv_pointers = std::make_unique<bv_pointerst>(
348  ns, *sat_solver, message_handler, get_array_constraints);
349 
350  if(options.get_option("arrays-uf") == "never")
351  bv_pointers->unbounded_array = bv_pointerst::unbounded_arrayt::U_NONE;
352  else if(options.get_option("arrays-uf") == "always")
353  bv_pointers->unbounded_array = bv_pointerst::unbounded_arrayt::U_ALL;
354 
355  set_decision_procedure_time_limit(*bv_pointers);
356 
357  return std::make_unique<solvert>(
358  std::move(bv_pointers), std::move(sat_solver));
359 }
360 
361 std::unique_ptr<solver_factoryt::solvert> solver_factoryt::get_dimacs()
362 {
365 
366  auto prop = std::make_unique<dimacs_cnft>(message_handler);
367 
368  std::string filename = options.get_option("outfile");
369 
370  auto bv_dimacs =
371  std::make_unique<bv_dimacst>(ns, *prop, message_handler, filename);
372 
373  return std::make_unique<solvert>(std::move(bv_dimacs), std::move(prop));
374 }
375 
376 std::unique_ptr<solver_factoryt::solvert> solver_factoryt::get_external_sat()
377 {
380 
381  std::string external_sat_solver = options.get_option("external-sat-solver");
382  auto prop =
383  std::make_unique<external_satt>(message_handler, external_sat_solver);
384 
385  auto bv_pointers = std::make_unique<bv_pointerst>(ns, *prop, message_handler);
386 
387  return std::make_unique<solvert>(std::move(bv_pointers), std::move(prop));
388 }
389 
390 std::unique_ptr<solver_factoryt::solvert> solver_factoryt::get_bv_refinement()
391 {
392  std::unique_ptr<propt> prop = get_sat_solver(message_handler, options);
393 
395  info.ns = &ns;
396  info.prop = prop.get();
398 
399  // we allow setting some parameters
400  if(options.get_bool_option("max-node-refinement"))
401  info.max_node_refinement =
402  options.get_unsigned_int_option("max-node-refinement");
403 
404  info.refine_arrays = options.get_bool_option("refine-arrays");
405  info.refine_arithmetic = options.get_bool_option("refine-arithmetic");
407 
408  auto decision_procedure = std::make_unique<bv_refinementt>(info);
409  set_decision_procedure_time_limit(*decision_procedure);
410  return std::make_unique<solvert>(
411  std::move(decision_procedure), std::move(prop));
412 }
413 
417 std::unique_ptr<solver_factoryt::solvert>
419 {
421  info.ns = &ns;
422  auto prop = get_sat_solver(message_handler, options);
423  info.prop = prop.get();
426  if(options.get_bool_option("max-node-refinement"))
427  info.max_node_refinement =
428  options.get_unsigned_int_option("max-node-refinement");
429  info.refine_arrays = options.get_bool_option("refine-arrays");
430  info.refine_arithmetic = options.get_bool_option("refine-arithmetic");
432 
433  auto decision_procedure = std::make_unique<string_refinementt>(info);
434  set_decision_procedure_time_limit(*decision_procedure);
435  return std::make_unique<solvert>(
436  std::move(decision_procedure), std::move(prop));
437 }
438 
439 std::unique_ptr<std::ofstream> open_outfile_and_check(
440  const std::string &filename,
442  const std::string &arg_name)
443 {
444  if(filename.empty())
445  return nullptr;
446 
447  auto out = std::make_unique<std::ofstream>(widen_if_needed(filename));
448 
449  if(!*out)
450  {
452  "failed to open file: " + filename, arg_name);
453  }
454 
456  log.status() << "Outputting SMTLib formula to file: " << filename
457  << messaget::eom;
458  return out;
459 }
460 
461 std::unique_ptr<solver_factoryt::solvert>
462 solver_factoryt::get_incremental_smt2(std::string solver_command)
463 {
465 
466  const std::string outfile_arg = options.get_option("outfile");
467  const std::string dump_smt_formula = options.get_option("dump-smt-formula");
468 
469  if(!outfile_arg.empty() && !dump_smt_formula.empty())
470  {
472  "Argument --outfile is incompatible with --dump-smt-formula. ",
473  "--outfile");
474  }
475 
476  std::unique_ptr<smt_base_solver_processt> solver_process = nullptr;
477 
478  if(!outfile_arg.empty())
479  {
480  bool on_std_out = outfile_arg == "-";
481  std::unique_ptr<std::ostream> outfile =
482  on_std_out
483  ? nullptr
484  : open_outfile_and_check(outfile_arg, message_handler, "--outfile");
485  solver_process = std::make_unique<smt_incremental_dry_run_solvert>(
486  message_handler, on_std_out ? std::cout : *outfile, std::move(outfile));
487  }
488  else
489  {
490  const auto out_filename = options.get_option("dump-smt-formula");
491 
492  // If no out_filename is provided `open_outfile_and_check` will return
493  // `nullptr`, and the solver will work normally without any logging.
494  solver_process = std::make_unique<smt_piped_solver_processt>(
495  std::move(solver_command),
498  out_filename, message_handler, "--dump-smt-formula"));
499  }
500 
501  return std::make_unique<solvert>(
502  std::make_unique<smt2_incremental_decision_proceduret>(
503  ns, std::move(solver_process), message_handler));
504 }
505 
506 std::unique_ptr<solver_factoryt::solvert>
508 {
510 
511  const std::string &filename = options.get_option("outfile");
512 
513  if(filename.empty())
514  {
516  {
518  "required filename not provided",
519  "--outfile",
520  "provide a filename with --outfile");
521  }
522 
523  auto smt2_dec = std::make_unique<smt2_dect>(
524  ns,
525  "cbmc",
526  std::string("Generated by CBMC ") + CBMC_VERSION,
527  "QF_AUFBV",
528  solver,
530 
531  if(options.get_bool_option("fpa"))
532  smt2_dec->use_FPA_theory = true;
533 
535  return std::make_unique<solvert>(std::move(smt2_dec));
536  }
537  else if(filename == "-")
538  {
539  auto smt2_conv = std::make_unique<smt2_convt>(
540  ns,
541  "cbmc",
542  std::string("Generated by CBMC ") + CBMC_VERSION,
543  "QF_AUFBV",
544  solver,
545  std::cout);
546 
547  if(options.get_bool_option("fpa"))
548  smt2_conv->use_FPA_theory = true;
549 
551  return std::make_unique<solvert>(std::move(smt2_conv));
552  }
553  else
554  {
555  auto out = open_outfile_and_check(filename, message_handler, "--outfile");
556 
557  auto smt2_conv = std::make_unique<smt2_convt>(
558  ns,
559  "cbmc",
560  std::string("Generated by CBMC ") + CBMC_VERSION,
561  "QF_AUFBV",
562  solver,
563  *out);
564 
565  if(options.get_bool_option("fpa"))
566  smt2_conv->use_FPA_theory = true;
567 
569  return std::make_unique<solvert>(std::move(smt2_conv), std::move(out));
570  }
571 }
572 
574 {
575  if(options.get_bool_option("beautify"))
576  {
578  "the chosen solver does not support beautification", "--beautify");
579  }
580 }
581 
583 {
584  const bool all_properties = options.get_bool_option("all-properties");
585  const bool cover = options.is_set("cover");
586  const bool incremental_loop = options.is_set("incremental-loop");
587 
588  if(all_properties)
589  {
591  "the chosen solver does not support incremental solving",
592  "--all_properties");
593  }
594  else if(cover)
595  {
597  "the chosen solver does not support incremental solving", "--cover");
598  }
599  else if(incremental_loop)
600  {
602  "the chosen solver does not support incremental solving",
603  "--incremental-loop");
604  }
605 }
606 
607 static void parse_sat_options(const cmdlinet &cmdline, optionst &options)
608 {
609  if(cmdline.isset("external-sat-solver"))
610  {
612  "external-sat-solver", cmdline.get_value("external-sat-solver"));
613  }
614 
615  options.set_option("sat-preprocessor", !cmdline.isset("no-sat-preprocessor"));
616 
617  if(cmdline.isset("dimacs"))
618  options.set_option("dimacs", true);
619 
620  if(cmdline.isset("sat-solver"))
621  options.set_option("sat-solver", cmdline.get_value("sat-solver"));
622 }
623 
624 static void parse_smt2_options(const cmdlinet &cmdline, optionst &options)
625 {
626  if(cmdline.isset("smt2"))
627  options.set_option("smt2", true);
628 
629  if(cmdline.isset("fpa"))
630  options.set_option("fpa", true);
631 
632  bool solver_set = false;
633 
634  if(cmdline.isset("bitwuzla"))
635  {
636  options.set_option("bitwuzla", true), solver_set = true;
637  options.set_option("smt2", true);
638  }
639 
640  if(cmdline.isset("boolector"))
641  {
642  options.set_option("boolector", true), solver_set = true;
643  options.set_option("smt2", true);
644  }
645 
646  if(cmdline.isset("cprover-smt2"))
647  {
648  options.set_option("cprover-smt2", true), solver_set = true;
649  options.set_option("smt2", true);
650  }
651 
652  if(cmdline.isset("mathsat"))
653  {
654  options.set_option("mathsat", true), solver_set = true;
655  options.set_option("smt2", true);
656  }
657 
658  if(cmdline.isset("cvc4"))
659  {
660  options.set_option("cvc4", true), solver_set = true;
661  options.set_option("smt2", true);
662  }
663 
664  if(cmdline.isset("cvc5"))
665  {
666  options.set_option("cvc5", true), solver_set = true;
667  options.set_option("smt2", true);
668  }
669 
670  if(cmdline.isset("incremental-smt2-solver"))
671  {
673  "incremental-smt2-solver", cmdline.get_value("incremental-smt2-solver")),
674  solver_set = true;
675  }
676 
677  if(cmdline.isset("yices"))
678  {
679  options.set_option("yices", true), solver_set = true;
680  options.set_option("smt2", true);
681  }
682 
683  if(cmdline.isset("z3"))
684  {
685  options.set_option("z3", true), solver_set = true;
686  options.set_option("smt2", true);
687  }
688 
689  if(cmdline.isset("smt2") && !solver_set)
690  {
691  if(cmdline.isset("outfile"))
692  {
693  // outfile and no solver should give standard compliant SMT-LIB
694  options.set_option("generic", true);
695  }
696  else
697  {
698  // the default smt2 solver
699  options.set_option("z3", true);
700  }
701  }
702 }
703 
705 {
706  parse_sat_options(cmdline, options);
707  parse_smt2_options(cmdline, options);
708 
709  if(cmdline.isset("outfile"))
710  options.set_option("outfile", cmdline.get_value("outfile"));
711 
712  if(cmdline.isset("dump-smt-formula"))
714  "dump-smt-formula", cmdline.get_value("dump-smt-formula"));
715 
716  if(cmdline.isset("write-solver-stats-to"))
717  {
719  "write-solver-stats-to", cmdline.get_value("write-solver-stats-to"));
720  }
721 
722  if(cmdline.isset("beautify"))
723  options.set_option("beautify", true);
724 
725  if(cmdline.isset("refine-arrays"))
726  {
727  options.set_option("refine", true);
728  options.set_option("refine-arrays", true);
729  }
730 
731  if(cmdline.isset("refine-arithmetic"))
732  {
733  options.set_option("refine", true);
734  options.set_option("refine-arithmetic", true);
735  }
736 
737  if(cmdline.isset("refine"))
738  {
739  options.set_option("refine", true);
740  options.set_option("refine-arrays", true);
741  options.set_option("refine-arithmetic", true);
742  }
743 
744  if(cmdline.isset("max-node-refinement"))
745  {
747  "max-node-refinement", cmdline.get_value("max-node-refinement"));
748  }
749 }
Writing DIMACS Files.
Abstraction Refinement Loop.
std::string get_value(char option) const
Definition: cmdline.cpp:48
virtual bool isset(char option) const
Definition: cmdline.cpp:30
An interface for a decision procedure for satisfiability problems.
virtual std::string decision_procedure_text() const =0
Return a textual description of the decision procedure.
Thrown when users pass incorrect command line arguments, for example passing no files to analysis or ...
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:155
static eomt eom
Definition: message.h:297
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
unsigned int get_unsigned_int_option(const std::string &option) const
Definition: options.cpp:56
bool is_set(const std::string &option) const
N.B. opts.is_set("foo") does not imply opts.get_bool_option("foo")
Definition: options.cpp:62
bool get_bool_option(const std::string &option) const
Definition: options.cpp:44
void set_option(const std::string &option, const bool value)
Definition: options.cpp:28
const std::string get_option(const std::string &option) const
Definition: options.cpp:67
signed int get_signed_int_option(const std::string &option) const
Definition: options.cpp:50
solvert(std::unique_ptr< decision_proceduret > p)
void set_decision_procedure(std::unique_ptr< decision_proceduret > p)
decision_proceduret & decision_procedure() const
stack_decision_proceduret & stack_decision_procedure() const
void set_ofstream(std::unique_ptr< std::ofstream > p)
void set_prop(std::unique_ptr< propt > p)
message_handlert & message_handler
const optionst & options
const namespacet & ns
std::unique_ptr< solvert > get_external_sat()
std::unique_ptr< solvert > get_default()
solver_factoryt(const optionst &_options, const namespacet &_ns, message_handlert &_message_handler, bool _output_xml_in_refinement)
Note: The solver returned will hold a reference to the namespace ns.
std::unique_ptr< solvert > get_dimacs()
void set_decision_procedure_time_limit(decision_proceduret &decision_procedure)
Sets the timeout of decision_procedure if the solver-time-limit option has a positive value (in secon...
std::unique_ptr< solvert > get_string_refinement()
the string refinement adds to the bit vector refinement specifications for functions from the Java st...
std::unique_ptr< solvert > get_smt2(smt2_dect::solvert solver)
const bool output_xml_in_refinement
smt2_dect::solvert get_smt2_solver_type() const
Uses the options to pick an SMT 2.0 solver.
virtual std::unique_ptr< solvert > get_solver()
Returns a solvert object.
std::unique_ptr< solvert > get_incremental_smt2(std::string solver_command)
std::unique_ptr< solvert > get_bv_refinement()
Document and give macros for the exit codes of CPROVER binaries.
#define CPROVER_EXIT_USAGE_ERROR
A usage error is returned when the command line is invalid or conflicting.
Definition: exit_codes.h:33
Allows calling an external SAT solver to allow faster integration of newer SAT solvers.
double log(double x)
Definition: math.c:2776
Options.
Decision procedure with incremental SMT2 solving.
void solver(std::vector< framet > &frames, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const solver_optionst &solver_options, const namespacet &ns, std::vector< propertyt > &properties, std::size_t property_index)
Definition: solver.cpp:44
static void parse_sat_options(const cmdlinet &cmdline, optionst &options)
static std::unique_ptr< propt > get_sat_solver(message_handlert &message_handler, const optionst &options)
static void parse_smt2_options(const cmdlinet &cmdline, optionst &options)
std::unique_ptr< std::ofstream > open_outfile_and_check(const std::string &filename, message_handlert &message_handler, const std::string &arg_name)
void parse_solver_options(const cmdlinet &cmdline, optionst &options)
Parse solver-related command-line parameters in cmdline and set corresponding values in options.
static void emit_solver_warning(message_handlert &message_handler, const std::string &solver)
Emit a warning for non-existent solver solver via message_handler.
static std::unique_ptr< SatcheckT > make_satcheck_prop(message_handlert &message_handler, const optionst &options)
Solver Factory.
Solver capability to set resource limits.
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
Decision procedure with incremental solving with contexts and assumptions.
void exit(int status)
Definition: stdlib.c:102
String support via creating string constraints and progressively instantiating the universal constrai...
#define DEFAULT_MAX_NB_REFINEMENT
unsigned max_node_refinement
Max number of times we refine a formula node.
Definition: bv_refinement.h:26
bool refine_arrays
Enable array refinement.
Definition: bv_refinement.h:28
bool refine_arithmetic
Enable arithmetic refinement.
Definition: bv_refinement.h:30
const namespacet * ns
Definition: bv_refinement.h:35
message_handlert * message_handler
Definition: bv_refinement.h:37
string_refinementt constructor arguments
#define widen_if_needed(s)
Definition: unicode.h:28
const char * CBMC_VERSION