mirror of
https://github.com/Z3Prover/z3
synced 2025-06-06 22:23:22 +00:00
add PB operators to C-based API
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
133ba2d02a
commit
d1937b2032
8 changed files with 77 additions and 3 deletions
|
@ -949,6 +949,11 @@ def def_API(name, result, params):
|
||||||
log_c.write(" }\n")
|
log_c.write(" }\n")
|
||||||
log_c.write(" Au(a%s);\n" % sz)
|
log_c.write(" Au(a%s);\n" % sz)
|
||||||
exe_c.write("in.get_uint_array(%s)" % i)
|
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:
|
else:
|
||||||
error ("unsupported parameter for %s, %s" % (name, p))
|
error ("unsupported parameter for %s, %s" % (name, p))
|
||||||
elif kind == OUT_ARRAY:
|
elif kind == OUT_ARRAY:
|
||||||
|
|
|
@ -874,6 +874,12 @@ typedef enum
|
||||||
|
|
||||||
- Z3_OP_DT_ACCESSOR: datatype accessor.
|
- 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.
|
- Z3_OP_UNINTERPRETED: kind used for uninterpreted symbols.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -1054,6 +1060,10 @@ typedef enum {
|
||||||
Z3_OP_DT_RECOGNISER,
|
Z3_OP_DT_RECOGNISER,
|
||||||
Z3_OP_DT_ACCESSOR,
|
Z3_OP_DT_ACCESSOR,
|
||||||
|
|
||||||
|
// Pseudo Booleans
|
||||||
|
Z3_OP_PB_AT_MOST=0x900,
|
||||||
|
Z3_OP_PB_LE,
|
||||||
|
|
||||||
Z3_OP_UNINTERPRETED
|
Z3_OP_UNINTERPRETED
|
||||||
} Z3_decl_kind;
|
} 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);
|
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
|
\mlonly {3 {L Function Declarations}} \endmlonly
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct z3_replayer::imp {
|
||||||
size_t_map<void *> m_heap;
|
size_t_map<void *> m_heap;
|
||||||
svector<z3_replayer_cmd> m_cmds;
|
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 {
|
struct value {
|
||||||
value_kind m_kind;
|
value_kind m_kind;
|
||||||
|
@ -68,6 +68,7 @@ struct z3_replayer::imp {
|
||||||
vector<ptr_vector<void> > m_obj_arrays;
|
vector<ptr_vector<void> > m_obj_arrays;
|
||||||
vector<svector<Z3_symbol> > m_sym_arrays;
|
vector<svector<Z3_symbol> > m_sym_arrays;
|
||||||
vector<unsigned_vector> m_unsigned_arrays;
|
vector<unsigned_vector> m_unsigned_arrays;
|
||||||
|
vector<svector<int> > m_int_arrays;
|
||||||
|
|
||||||
imp(z3_replayer & o, std::istream & in):
|
imp(z3_replayer & o, std::istream & in):
|
||||||
m_owner(o),
|
m_owner(o),
|
||||||
|
@ -295,6 +296,15 @@ struct z3_replayer::imp {
|
||||||
v.push_back(static_cast<unsigned>(m_args[i].m_uint));
|
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) {
|
else if (k == SYMBOL) {
|
||||||
aidx = m_sym_arrays.size();
|
aidx = m_sym_arrays.size();
|
||||||
nk = SYMBOL_ARRAY;
|
nk = SYMBOL_ARRAY;
|
||||||
|
@ -547,6 +557,13 @@ struct z3_replayer::imp {
|
||||||
return m_unsigned_arrays[idx].c_ptr();
|
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 {
|
Z3_symbol * get_symbol_array(unsigned pos) const {
|
||||||
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL_ARRAY)
|
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL_ARRAY)
|
||||||
throw_invalid_reference();
|
throw_invalid_reference();
|
||||||
|
@ -615,6 +632,7 @@ struct z3_replayer::imp {
|
||||||
m_obj_arrays.reset();
|
m_obj_arrays.reset();
|
||||||
m_sym_arrays.reset();
|
m_sym_arrays.reset();
|
||||||
m_unsigned_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);
|
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 {
|
Z3_symbol * z3_replayer::get_symbol_array(unsigned pos) const {
|
||||||
return m_imp->get_symbol_array(pos);
|
return m_imp->get_symbol_array(pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ public:
|
||||||
void * get_obj(unsigned pos) const;
|
void * get_obj(unsigned pos) const;
|
||||||
|
|
||||||
unsigned * get_uint_array(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;
|
Z3_symbol * get_symbol_array(unsigned pos) const;
|
||||||
void ** get_obj_array(unsigned pos) const;
|
void ** get_obj_array(unsigned pos) const;
|
||||||
|
|
||||||
|
|
|
@ -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, ¶m, num_args, args, m.mk_bool_sort());
|
return m.mk_app(m_fid, OP_AT_MOST_K, 1, ¶m, 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 {
|
bool card_util::is_at_most_k(app *a) const {
|
||||||
return is_app_of(a, m_fid, OP_AT_MOST_K);
|
return is_app_of(a, m_fid, OP_AT_MOST_K);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,9 @@ class card_util {
|
||||||
public:
|
public:
|
||||||
card_util(ast_manager& m):m(m), m_fid(m.mk_family_id("card")) {}
|
card_util(ast_manager& m):m(m), m_fid(m.mk_family_id("card")) {}
|
||||||
ast_manager & get_manager() const { return m; }
|
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_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) const;
|
||||||
bool is_at_most_k(app *a, unsigned& k) const;
|
bool is_at_most_k(app *a, unsigned& k) const;
|
||||||
int get_k(app *a) const;
|
int get_k(app *a) const;
|
||||||
|
|
|
@ -65,6 +65,7 @@ namespace opt {
|
||||||
for (unsigned i = 0; i < ans.size(); ++i) {
|
for (unsigned i = 0; i < ans.size(); ++i) {
|
||||||
tout << mk_pp(ans[i].get(), m) << "\n";
|
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()) {
|
if (ans.size() > m_answer.size()) {
|
||||||
m_answer.reset();
|
m_answer.reset();
|
||||||
m_answer.append(ans);
|
m_answer.append(ans);
|
||||||
|
@ -91,6 +92,7 @@ namespace opt {
|
||||||
core_vars.insert(get_not(core[i]));
|
core_vars.insert(get_not(core[i]));
|
||||||
block_vars.remove(core[i]);
|
block_vars.remove(core[i]);
|
||||||
}
|
}
|
||||||
|
IF_VERBOSE(1, verbose_stream() << "(maxsat.core unsat (core size = " << core.size() << ")\n";);
|
||||||
if (core.empty()) {
|
if (core.empty()) {
|
||||||
m_upper = m_answer.size();
|
m_upper = m_answer.size();
|
||||||
return l_true;
|
return l_true;
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace opt {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
lbool step() {
|
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);
|
expr_ref_vector assumptions(m), block_vars(m);
|
||||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||||
assumptions.push_back(m.mk_not(m_aux[i].get()));
|
assumptions.push_back(m.mk_not(m_aux[i].get()));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue