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:
parent
133ba2d02a
commit
d1937b2032
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()));
|
||||
|
|
Loading…
Reference in a new issue