3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-08 10:25:18 +00:00

add PB operators to C-based API

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2013-11-13 17:09:10 -08:00
parent 133ba2d02a
commit d1937b2032
8 changed files with 77 additions and 3 deletions

View file

@ -949,6 +949,11 @@ def def_API(name, result, params):
log_c.write(" }\n")
log_c.write(" Au(a%s);\n" % sz)
exe_c.write("in.get_uint_array(%s)" % i)
elif ty == INT:
log_c.write("U(a%s[i]);" % i)
log_c.write(" }\n")
log_c.write(" Au(a%s);\n" % sz)
exe_c.write("in.get_int_array(%s)" % i)
else:
error ("unsupported parameter for %s, %s" % (name, p))
elif kind == OUT_ARRAY:

View file

@ -874,6 +874,12 @@ typedef enum
- Z3_OP_DT_ACCESSOR: datatype accessor.
- Z3_OP_PB_AT_MOST: Cardinality constraint.
E.g., x + y + z <= 2
- Z3_OP_PB_LE: Generalized Pseudo-Boolean cardinality constraint.
Example 2*x + 3*y <= 4
- Z3_OP_UNINTERPRETED: kind used for uninterpreted symbols.
*/
typedef enum {
@ -1054,6 +1060,10 @@ typedef enum {
Z3_OP_DT_RECOGNISER,
Z3_OP_DT_ACCESSOR,
// Pseudo Booleans
Z3_OP_PB_AT_MOST=0x900,
Z3_OP_PB_LE,
Z3_OP_UNINTERPRETED
} Z3_decl_kind;
@ -3758,6 +3768,29 @@ END_MLAPI_EXCLUDE
Z3_sort Z3_API Z3_get_relation_column(__in Z3_context c, __in Z3_sort s, unsigned col);
/**
\brief Pseudo-Boolean relations.
Encode p1 + p2 + ... + pn <= k
def_API('Z3_mk_atmost', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in(UINT)))
*/
Z3_ast Z3_API Z3_mk_atmost(__in Z3_context c, __in unsigned num_args,
__in_ecount(num_args) Z3_ast const args[], __in unsigned k);
/**
\brief Pseudo-Boolean relations.
Encode k1*p1 + k2*p2 + ... + kn*pn <= k
def_API('Z3_mk_pble', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in_array(1,INT), _in(INT)))
*/
Z3_ast Z3_API Z3_mk_pble(__in Z3_context c, __in unsigned num_args,
__in_ecount(num_args) Z3_ast const args[], __in_ecount(num_args) int coeffs[],
__in int k);
/**
\mlonly {3 {L Function Declarations}} \endmlonly
*/

View file

@ -44,7 +44,7 @@ struct z3_replayer::imp {
size_t_map<void *> m_heap;
svector<z3_replayer_cmd> m_cmds;
enum value_kind { INT64, UINT64, DOUBLE, STRING, SYMBOL, OBJECT, UINT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY };
enum value_kind { INT64, UINT64, DOUBLE, STRING, SYMBOL, OBJECT, UINT_ARRAY, INT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY };
struct value {
value_kind m_kind;
@ -68,6 +68,7 @@ struct z3_replayer::imp {
vector<ptr_vector<void> > m_obj_arrays;
vector<svector<Z3_symbol> > m_sym_arrays;
vector<unsigned_vector> m_unsigned_arrays;
vector<svector<int> > m_int_arrays;
imp(z3_replayer & o, std::istream & in):
m_owner(o),
@ -295,6 +296,15 @@ struct z3_replayer::imp {
v.push_back(static_cast<unsigned>(m_args[i].m_uint));
}
}
if (k == INT64) {
aidx = m_int_arrays.size();
nk = INT_ARRAY;
m_int_arrays.push_back(svector<int>());
svector<int> & v = m_int_arrays.back();
for (unsigned i = asz - sz; i < asz; i++) {
v.push_back(static_cast<int>(m_args[i].m_int));
}
}
else if (k == SYMBOL) {
aidx = m_sym_arrays.size();
nk = SYMBOL_ARRAY;
@ -547,6 +557,13 @@ struct z3_replayer::imp {
return m_unsigned_arrays[idx].c_ptr();
}
int * get_int_array(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != INT_ARRAY)
throw_invalid_reference();
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
return m_int_arrays[idx].c_ptr();
}
Z3_symbol * get_symbol_array(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL_ARRAY)
throw_invalid_reference();
@ -615,6 +632,7 @@ struct z3_replayer::imp {
m_obj_arrays.reset();
m_sym_arrays.reset();
m_unsigned_arrays.reset();
m_int_arrays.reset();
}
@ -673,6 +691,10 @@ unsigned * z3_replayer::get_uint_array(unsigned pos) const {
return m_imp->get_uint_array(pos);
}
int * z3_replayer::get_int_array(unsigned pos) const {
return m_imp->get_int_array(pos);
}
Z3_symbol * z3_replayer::get_symbol_array(unsigned pos) const {
return m_imp->get_symbol_array(pos);
}

View file

@ -49,6 +49,7 @@ public:
void * get_obj(unsigned pos) const;
unsigned * get_uint_array(unsigned pos) const;
int * get_int_array(unsigned pos) const;
Z3_symbol * get_symbol_array(unsigned pos) const;
void ** get_obj_array(unsigned pos) const;

View file

@ -72,6 +72,16 @@ app * card_util::mk_at_most_k(unsigned num_args, expr * const * args, unsigned k
return m.mk_app(m_fid, OP_AT_MOST_K, 1, &param, num_args, args, m.mk_bool_sort());
}
app * card_util::mk_le(unsigned num_args, int const * coeffs, expr * const * args, int k) {
vector<parameter> params;
params.push_back(parameter(k));
for (unsigned i = 0; i < num_args; ++i) {
params.push_back(parameter(coeffs[i]));
}
return m.mk_app(m_fid, OP_PB_LE, params.size(), params.c_ptr(), num_args, args, m.mk_bool_sort());
}
bool card_util::is_at_most_k(app *a) const {
return is_app_of(a, m_fid, OP_AT_MOST_K);
}

View file

@ -71,8 +71,9 @@ class card_util {
public:
card_util(ast_manager& m):m(m), m_fid(m.mk_family_id("card")) {}
ast_manager & get_manager() const { return m; }
family_id get_family_id() const { return m_fid; }
app * mk_at_most_k(unsigned num_args, expr * const * args, unsigned k);
app * mk_le(unsigned num_args, int * const* coeffs, expr * const * args, int k);
app * mk_le(unsigned num_args, int const * coeffs, expr * const * args, int k);
bool is_at_most_k(app *a) const;
bool is_at_most_k(app *a, unsigned& k) const;
int get_k(app *a) const;

View file

@ -65,6 +65,7 @@ namespace opt {
for (unsigned i = 0; i < ans.size(); ++i) {
tout << mk_pp(ans[i].get(), m) << "\n";
});
IF_VERBOSE(1, verbose_stream() << "(maxsat.core sat: " << ans.size() << "\n";);
if (ans.size() > m_answer.size()) {
m_answer.reset();
m_answer.append(ans);
@ -91,6 +92,7 @@ namespace opt {
core_vars.insert(get_not(core[i]));
block_vars.remove(core[i]);
}
IF_VERBOSE(1, verbose_stream() << "(maxsat.core unsat (core size = " << core.size() << ")\n";);
if (core.empty()) {
m_upper = m_answer.size();
return l_true;

View file

@ -73,7 +73,7 @@ namespace opt {
*/
lbool step() {
IF_VERBOSE(1, verbose_stream() << "(opt.max_sat step)\n";);
IF_VERBOSE(1, verbose_stream() << "(opt.max_sat step)\n";); // add some count, add some information of # of soft constraints still possibly sat.
expr_ref_vector assumptions(m), block_vars(m);
for (unsigned i = 0; i < m_soft.size(); ++i) {
assumptions.push_back(m.mk_not(m_aux[i].get()));