mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
saved params work
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
c3055207ed
commit
cf28cbab0a
130 changed files with 1469 additions and 948 deletions
|
@ -40,7 +40,7 @@ public:
|
|||
double_manager(params_ref const & p = params_ref()) { updt_params(p); }
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
m_zero_tolerance = p.get_double(":zero-tolerance", 0.00000001);
|
||||
m_zero_tolerance = p.get_double("zero_tolerance", 0.00000001);
|
||||
}
|
||||
|
||||
static void reset(double & a) { a = 0.0; }
|
||||
|
|
249
src/util/gparams.cpp
Normal file
249
src/util/gparams.cpp
Normal file
|
@ -0,0 +1,249 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
gparams.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Global parameter management.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2012-11-29
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"gparams.h"
|
||||
#include"dictionary.h"
|
||||
|
||||
extern void gparams_register_modules();
|
||||
|
||||
struct gparams::imp {
|
||||
dictionary<param_descrs*> m_module_param_descrs;
|
||||
param_descrs m_param_descrs;
|
||||
dictionary<params_ref *> m_module_params;
|
||||
params_ref m_params;
|
||||
params_ref m_empty;
|
||||
public:
|
||||
imp() {
|
||||
}
|
||||
|
||||
~imp() {
|
||||
{
|
||||
dictionary<param_descrs*>::iterator it = m_module_param_descrs.begin();
|
||||
dictionary<param_descrs*>::iterator end = m_module_param_descrs.end();
|
||||
for (; it != end; ++it) {
|
||||
dealloc(it->m_value);
|
||||
}
|
||||
}
|
||||
{
|
||||
dictionary<params_ref*>::iterator it = m_module_params.begin();
|
||||
dictionary<params_ref*>::iterator end = m_module_params.end();
|
||||
for (; it != end; ++it) {
|
||||
dealloc(it->m_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void register_global(param_descrs & d) {
|
||||
m_param_descrs.copy(d);
|
||||
}
|
||||
|
||||
void register_module(char const * module_name, param_descrs * d) {
|
||||
symbol s(module_name);
|
||||
param_descrs * old_d;
|
||||
if (m_module_param_descrs.find(s, old_d)) {
|
||||
old_d->copy(*d);
|
||||
dealloc(d);
|
||||
}
|
||||
else {
|
||||
m_module_param_descrs.insert(s, d);
|
||||
}
|
||||
}
|
||||
|
||||
void display(std::ostream & out, unsigned indent, bool smt2_style) {
|
||||
m_param_descrs.display(out, indent, smt2_style);
|
||||
dictionary<param_descrs*>::iterator it = m_module_param_descrs.begin();
|
||||
dictionary<param_descrs*>::iterator end = m_module_param_descrs.end();
|
||||
for (; it != end; ++it) {
|
||||
out << "[module] " << it->m_key << "\n";
|
||||
it->m_value->display(out, indent + 4, smt2_style);
|
||||
}
|
||||
}
|
||||
|
||||
void normalize(char const * name, /* out */ symbol & mod_name, /* out */ symbol & param_name) {
|
||||
if (*name == ':')
|
||||
name++;
|
||||
std::string tmp = name;
|
||||
unsigned n = tmp.size();
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
if (tmp[i] >= 'A' && tmp[i] <= 'Z')
|
||||
tmp[i] = tmp[i] - 'A' + 'a';
|
||||
else if (tmp[i] == '-')
|
||||
tmp[i] = '_';
|
||||
}
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
if (tmp[i] == '.') {
|
||||
param_name = tmp.substr(i+1).c_str();
|
||||
tmp.resize(i);
|
||||
mod_name = tmp.c_str();
|
||||
return;
|
||||
}
|
||||
}
|
||||
param_name = tmp.c_str();
|
||||
mod_name = symbol::null;
|
||||
}
|
||||
|
||||
params_ref & get_params(symbol const & mod_name) {
|
||||
if (mod_name == symbol::null) {
|
||||
return m_params;
|
||||
}
|
||||
else {
|
||||
params_ref * p;
|
||||
if (m_module_params.find(mod_name, p)) {
|
||||
return *p;
|
||||
}
|
||||
else {
|
||||
p = alloc(params_ref);
|
||||
m_module_params.insert(mod_name, p);
|
||||
return *p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set(param_descrs const & d, symbol const & param_name, char const * value, symbol const & mod_name) {
|
||||
param_kind k = d.get_kind(param_name);
|
||||
params_ref & ps = get_params(mod_name);
|
||||
if (k == CPK_INVALID) {
|
||||
if (mod_name == symbol::null)
|
||||
throw default_exception("unknown parameter '%s'", param_name.bare_str());
|
||||
else
|
||||
throw default_exception("unknown parameter '%s' at module '%s'", param_name.bare_str(), mod_name.bare_str());
|
||||
}
|
||||
else if (k == CPK_UINT) {
|
||||
long val = strtol(value, 0, 10);
|
||||
ps.set_uint(param_name, static_cast<unsigned>(val));
|
||||
}
|
||||
else if (k == CPK_BOOL) {
|
||||
if (strcmp(value, "true") == 0) {
|
||||
ps.set_bool(param_name, true);
|
||||
}
|
||||
else if (strcmp(value, "false") == 0) {
|
||||
ps.set_bool(param_name, false);
|
||||
}
|
||||
else {
|
||||
if (mod_name == symbol::null)
|
||||
throw default_exception("invalid value '%s' for Boolean parameter '%s'", value, param_name.bare_str());
|
||||
else
|
||||
throw default_exception("invalid value '%s' for Boolean parameter '%s' at module '%s'", value, param_name.bare_str(), mod_name.bare_str());
|
||||
}
|
||||
}
|
||||
else if (k == CPK_SYMBOL) {
|
||||
ps.set_sym(param_name, symbol(value));
|
||||
}
|
||||
else if (k == CPK_STRING) {
|
||||
ps.set_str(param_name, value);
|
||||
}
|
||||
else {
|
||||
if (mod_name == symbol::null)
|
||||
throw default_exception("unsupported parameter type '%s'", param_name.bare_str());
|
||||
else
|
||||
throw default_exception("unsupported parameter type '%s' at module '%s'", param_name.bare_str(), mod_name.bare_str());
|
||||
}
|
||||
}
|
||||
|
||||
void set(char const * name, char const * value) {
|
||||
symbol m, p;
|
||||
normalize(name, m, p);
|
||||
if (m == symbol::null) {
|
||||
set(m_param_descrs, p, value, m);
|
||||
}
|
||||
else {
|
||||
param_descrs * d;
|
||||
if (m_module_param_descrs.find(m, d)) {
|
||||
set(*d, p, value, m);
|
||||
}
|
||||
else {
|
||||
throw default_exception("invalid parameter, unknown module '%s'", m.bare_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_value(char const * name) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
params_ref const & get_module(symbol const & module_name) {
|
||||
params_ref * ps = 0;
|
||||
if (m_module_params.find(module_name, ps)) {
|
||||
return *ps;
|
||||
}
|
||||
else {
|
||||
return m_empty;
|
||||
}
|
||||
}
|
||||
|
||||
params_ref const & get() {
|
||||
return m_params;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
gparams::imp * gparams::g_imp = 0;
|
||||
|
||||
void gparams::set(char const * name, char const * value) {
|
||||
SASSERT(g_imp != 0);
|
||||
g_imp->set(name, value);
|
||||
}
|
||||
|
||||
std::string gparams::get_value(char const * name) {
|
||||
SASSERT(g_imp != 0);
|
||||
g_imp->get_value(name);
|
||||
}
|
||||
|
||||
void gparams::register_global(param_descrs & d) {
|
||||
SASSERT(g_imp != 0);
|
||||
g_imp->register_global(d);
|
||||
}
|
||||
|
||||
void gparams::register_module(char const * module_name, param_descrs * d) {
|
||||
SASSERT(g_imp != 0);
|
||||
g_imp->register_module(module_name, d);
|
||||
}
|
||||
|
||||
params_ref const & gparams::get_module(char const * module_name) {
|
||||
return get_module(symbol(module_name));
|
||||
}
|
||||
|
||||
params_ref const & gparams::get_module(symbol const & module_name) {
|
||||
SASSERT(g_imp != 0);
|
||||
return g_imp->get_module(module_name);
|
||||
}
|
||||
|
||||
params_ref const & gparams::get() {
|
||||
SASSERT(g_imp != 0);
|
||||
return g_imp->get();
|
||||
}
|
||||
|
||||
void gparams::display(std::ostream & out, unsigned indent, bool smt2_style) {
|
||||
SASSERT(g_imp != 0);
|
||||
g_imp->display(out, indent, smt2_style);
|
||||
}
|
||||
|
||||
void gparams::init() {
|
||||
g_imp = alloc(imp);
|
||||
gparams_register_modules();
|
||||
}
|
||||
|
||||
void gparams::finalize() {
|
||||
if (g_imp != 0) {
|
||||
dealloc(g_imp);
|
||||
g_imp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
122
src/util/gparams.h
Normal file
122
src/util/gparams.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
gparams.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Global parameter management.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2012-11-29
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _GPARAMS_H_
|
||||
#define _GPARAMS_H_
|
||||
|
||||
#include"params.h"
|
||||
|
||||
class gparams {
|
||||
struct imp;
|
||||
static imp * g_imp;
|
||||
typedef z3_exception exception;
|
||||
public:
|
||||
/**
|
||||
\brief Set a global parameter \c name with \c value.
|
||||
|
||||
The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'.
|
||||
The character '.' is used a delimiter (more later).
|
||||
|
||||
The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'.
|
||||
Thus, the following parameter names are considered equivalent: "auto-config" and "AUTO_CONFIG".
|
||||
|
||||
This function can be used to set parameters for a specific Z3 module.
|
||||
This can be done by using <module-name>.<parameter-name>.
|
||||
For example:
|
||||
set_global_param('pp.decimal', 'true')
|
||||
will set the parameter "decimal" in the module "pp" to true.
|
||||
|
||||
An exception is thrown if the the parameter name is unknown, or if the value is incorrect.
|
||||
*/
|
||||
static void set(char const * name, char const * value);
|
||||
|
||||
/**
|
||||
\brief Auxiliary method used to implement get-option in SMT 2.0 front-end.
|
||||
|
||||
If the parameter is not set, then it just returns 'default'.
|
||||
|
||||
An exception is thrown if the the parameter name is unknown.
|
||||
*/
|
||||
static std::string get_value(char const * name);
|
||||
|
||||
/**
|
||||
\brief Register additional global parameters
|
||||
|
||||
This is an auxiliary function used by our automatic code generator.
|
||||
Example: the directive REG_PARAMS('collect_param_descrs')
|
||||
"tells" the automatic code generator how to register the additional global parameters.
|
||||
*/
|
||||
static void register_global(param_descrs & d);
|
||||
|
||||
/**
|
||||
\brief Register parameter descriptions for a Z3 module.
|
||||
The parameters of a given Z3 module can only be set using #set_global_param if
|
||||
they are registered in this module using this function.
|
||||
|
||||
This is an auxiliary function used by our automatic code generator.
|
||||
Each module will contain directives (in comments) such as
|
||||
Example: the directive REG_MODULE_PARAMS('nlsat', 'nlsat::solver::collect_param_descrs')
|
||||
"tells" the automatic code generator how to register the parameters for the given
|
||||
module.
|
||||
*/
|
||||
static void register_module(char const * module_name, param_descrs * d);
|
||||
|
||||
/**
|
||||
\brief Retrieves the parameters associated with the given module.
|
||||
|
||||
Example:
|
||||
// The following command sets the parameter "decimal" in the module "pp" to true.
|
||||
set_global_param("pp.decimal", "true");
|
||||
...
|
||||
// The following command will return the global parameters that were set for the module "pp".
|
||||
// In this example "p" will contain "decimal" -> true after executing this function.
|
||||
params_ref const & p = get_module_params("pp")
|
||||
*/
|
||||
static params_ref const & get_module(char const * module_name);
|
||||
static params_ref const & get_module(symbol const & module_name);
|
||||
|
||||
/**
|
||||
\brief Return the global parameter set (i.e., parameters that are not associated with any particular module).
|
||||
*/
|
||||
static params_ref const & get();
|
||||
|
||||
/**
|
||||
\brief Dump information about available parameters in the given output stream.
|
||||
*/
|
||||
static void display(std::ostream & out, unsigned indent = 0, bool smt2_style=false);
|
||||
|
||||
/**
|
||||
\brief Initialize the global parameter management module.
|
||||
|
||||
Remark: I set a priority in the initialization, because this module must be initialized
|
||||
after the core modules such as symbol.
|
||||
ADD_INITIALIZER('gparams::init();', 1)
|
||||
*/
|
||||
static void init();
|
||||
|
||||
/**
|
||||
\brief Finalize the global parameter management module.
|
||||
|
||||
ADD_FINALIZER('gparams::finalize();');
|
||||
*/
|
||||
static void finalize();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -60,7 +60,7 @@ struct param_descrs::imp {
|
|||
bool operator()(symbol const & s1, symbol const & s2) const { return strcmp(s1.bare_str(), s2.bare_str()) < 0; }
|
||||
};
|
||||
|
||||
void display(std::ostream & out, unsigned indent) const {
|
||||
void display(std::ostream & out, unsigned indent, bool smt2_style) const {
|
||||
svector<symbol> names;
|
||||
dictionary<info>::iterator it = m_info.begin();
|
||||
dictionary<info>::iterator end = m_info.end();
|
||||
|
@ -72,7 +72,20 @@ struct param_descrs::imp {
|
|||
svector<symbol>::iterator end2 = names.end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
for (unsigned i = 0; i < indent; i++) out << " ";
|
||||
out << *it2;
|
||||
if (smt2_style)
|
||||
out << ':';
|
||||
char const * s = it2->bare_str();
|
||||
unsigned n = strlen(s);
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
if (smt2_style && s[i] == '_')
|
||||
out << '-';
|
||||
else if (!smt2_style && s[i] == '-')
|
||||
out << '_';
|
||||
else if (s[i] >= 'A' && s[i] <= 'Z')
|
||||
out << (s[i] - 'A' + 'a');
|
||||
else
|
||||
out << s[i];
|
||||
}
|
||||
info d;
|
||||
d.second = 0;
|
||||
m_info.find(*it2, d);
|
||||
|
@ -80,6 +93,15 @@ struct param_descrs::imp {
|
|||
out << " (" << d.first << ") " << d.second << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void copy(param_descrs & other) {
|
||||
dictionary<info>::iterator it = other.m_imp->m_info.begin();
|
||||
dictionary<info>::iterator end = other.m_imp->m_info.end();
|
||||
for (; it != end; ++it) {
|
||||
insert(it->m_key, it->m_value.first, it->m_value.second);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
param_descrs::param_descrs() {
|
||||
|
@ -90,6 +112,10 @@ param_descrs::~param_descrs() {
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
void param_descrs::copy(param_descrs & other) {
|
||||
m_imp->copy(other);
|
||||
}
|
||||
|
||||
void param_descrs::insert(symbol const & name, param_kind k, char const * descr) {
|
||||
m_imp->insert(name, k, descr);
|
||||
}
|
||||
|
@ -122,28 +148,28 @@ symbol param_descrs::get_param_name(unsigned i) const {
|
|||
return m_imp->get_param_name(i);
|
||||
}
|
||||
|
||||
void param_descrs::display(std::ostream & out, unsigned indent) const {
|
||||
return m_imp->display(out, indent);
|
||||
void param_descrs::display(std::ostream & out, unsigned indent, bool smt2_style) const {
|
||||
return m_imp->display(out, indent, smt2_style);
|
||||
}
|
||||
|
||||
void insert_max_memory(param_descrs & r) {
|
||||
r.insert(":max-memory", CPK_UINT, "(default: infty) maximum amount of memory in megabytes.");
|
||||
r.insert("max_memory", CPK_UINT, "(default: infty) maximum amount of memory in megabytes.");
|
||||
}
|
||||
|
||||
void insert_max_steps(param_descrs & r) {
|
||||
r.insert(":max-steps", CPK_UINT, "(default: infty) maximum number of steps.");
|
||||
r.insert("max_steps", CPK_UINT, "(default: infty) maximum number of steps.");
|
||||
}
|
||||
|
||||
void insert_produce_models(param_descrs & r) {
|
||||
r.insert(":produce-models", CPK_BOOL, "(default: false) model generation.");
|
||||
r.insert("produce_models", CPK_BOOL, "(default: false) model generation.");
|
||||
}
|
||||
|
||||
void insert_produce_proofs(param_descrs & r) {
|
||||
r.insert(":produce-proofs", CPK_BOOL, "(default: false) proof generation.");
|
||||
r.insert("produce_proofs", CPK_BOOL, "(default: false) proof generation.");
|
||||
}
|
||||
|
||||
void insert_timeout(param_descrs & r) {
|
||||
r.insert(":timeout", CPK_UINT, "(default: infty) timeout in milliseconds.");
|
||||
r.insert("timeout", CPK_UINT, "(default: infty) timeout in milliseconds.");
|
||||
}
|
||||
|
||||
class params {
|
||||
|
@ -255,6 +281,39 @@ public:
|
|||
}
|
||||
out << ")";
|
||||
}
|
||||
|
||||
void display(std::ostream & out, symbol const & k) const {
|
||||
svector<params::entry>::const_iterator it = m_entries.begin();
|
||||
svector<params::entry>::const_iterator end = m_entries.end();
|
||||
for (; it != end; ++it) {
|
||||
if (it->first != k)
|
||||
continue;
|
||||
switch (it->second.m_kind) {
|
||||
case CPK_BOOL:
|
||||
out << it->second.m_bool_value;
|
||||
return;
|
||||
case CPK_UINT:
|
||||
out << it->second.m_uint_value;
|
||||
return;
|
||||
case CPK_DOUBLE:
|
||||
out << it->second.m_double_value;
|
||||
return;
|
||||
case CPK_NUMERAL:
|
||||
out << *(it->second.m_rat_value);
|
||||
return;
|
||||
case CPK_SYMBOL:
|
||||
out << symbol::mk_symbol_from_c_ptr(it->second.m_sym_value);
|
||||
return;
|
||||
case CPK_STRING:
|
||||
out << it->second.m_str_value;
|
||||
return;
|
||||
default:
|
||||
out << "internal";
|
||||
return;
|
||||
}
|
||||
}
|
||||
out << "default";
|
||||
}
|
||||
};
|
||||
|
||||
params_ref::~params_ref() {
|
||||
|
@ -274,6 +333,17 @@ void params_ref::display(std::ostream & out) const {
|
|||
out << "(params)";
|
||||
}
|
||||
|
||||
void params_ref::display(std::ostream & out, char const * k) const {
|
||||
display(out, symbol(k));
|
||||
}
|
||||
|
||||
void params_ref::display(std::ostream & out, symbol const & k) const {
|
||||
if (m_params)
|
||||
m_params->display(out, k);
|
||||
else
|
||||
out << "default";
|
||||
}
|
||||
|
||||
void params_ref::validate(param_descrs const & p) const {
|
||||
if (m_params)
|
||||
m_params->validate(p);
|
||||
|
|
|
@ -79,6 +79,14 @@ public:
|
|||
void display(std::ostream & out) const;
|
||||
|
||||
void validate(param_descrs const & p) const;
|
||||
|
||||
/*
|
||||
\brief Display the value of the given parameter.
|
||||
|
||||
It displays 'default' if k is not in the parameter set.
|
||||
*/
|
||||
void display(std::ostream & out, char const * k);
|
||||
void display(std::ostream & out, symbol const & k);
|
||||
};
|
||||
|
||||
inline std::ostream & operator<<(std::ostream & out, params_ref const & ref) {
|
||||
|
@ -92,13 +100,14 @@ class param_descrs {
|
|||
public:
|
||||
param_descrs();
|
||||
~param_descrs();
|
||||
void copy(param_descrs & other);
|
||||
void insert(char const * name, param_kind k, char const * descr);
|
||||
void insert(symbol const & name, param_kind k, char const * descr);
|
||||
void erase(char const * name);
|
||||
void erase(symbol const & name);
|
||||
param_kind get_kind(char const * name) const;
|
||||
param_kind get_kind(symbol const & name) const;
|
||||
void display(std::ostream & out, unsigned indent = 0) const;
|
||||
void display(std::ostream & out, unsigned indent = 0, bool smt2_style=false) const;
|
||||
unsigned size() const;
|
||||
symbol get_param_name(unsigned idx) const;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue