Solver Wrapper Implementation for Solver

Solver wrappers derive a solver class from murxla::Solver, which manages construction and destruction of an instance of the solver under test. It further implements required and optional member function overrides.

Murxla uses naming convention <solver name (short)>Solver for solver wrapper solver implementations, e.g., the cvc5 implementation is called Cvc5Solver and the Bitwuzla implementation is called BitwuzlaSolver.

Note that the constructor of murxla::Solver is not to be overriden. A solver instance is created and deleted via the required member function overrides of functions murxla::Solver::new_solver() and murxla::Solver::delete_solver(). For example, in the solver wrapper for cvc5 (using its C++ API) these are implemented as follows:

void
Cvc5Solver::new_solver()
{
  assert(d_solver == nullptr);
  d_solver = new ::cvc5::Solver();
  d_tracer.init();
  // Incremental solving is enabled by default via cvc5's API. We disable it
  // when creating a new solver instance and explicitly enable it later on in
  // order to correctly trace the option.
  TRACE_SOLVER(setOption, "incremental", "false");
}
void
Cvc5Solver::delete_solver()
{
  assert(d_solver != nullptr);
  delete d_solver;
  d_solver = nullptr;
}

Another example for a required override is member function murxla::Solver::get_name(), which returns the name of the solver under test. It is implemented for cvc5 as follows:

const std::string
Cvc5Solver::get_name() const
{
  return "cvc5";
}

An example for an optional override is member function murxla::Solver::get_unsat_core(), which returns a vector of terms representing the unsat core of the currently asserted formula. It is implemented in the solver wrapper for Bitwuzla (using its C API) as follows:

std::vector<Term>
BitwuzlaSolver::get_unsat_core()
{
  assert(d_solver != nullptr);
  return BitwuzlaTerm::bitwuzla_terms_to_terms(d_tm.get(),
                                               d_solver->get_unsat_core());
}

Note

Optional overrides have default implementations, but should be overriden if supported by the solver.