z3-z3-4.13.0.src.test.theory_pb.cpp Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2015 Microsoft Corporation
--*/
#include "smt/smt_context.h"
#include "ast/ast_pp.h"
#include "model/model_v2_pp.h"
#include "ast/reg_decl_plugins.h"
#include "smt/theory_pb.h"
#include "ast/rewriter/th_rewriter.h"
#include
static unsigned populate_literals(unsigned k, smt::literal_vector& lits) {
ENSURE(k < (1u << lits.size()));
unsigned t = 0;
for (unsigned i = 0; i < lits.size(); ++i) {
if (k & (1 << i)) {
lits[i] = smt::true_literal;
t++;
}
else {
lits[i] = smt::false_literal;
}
}
return t;
}
class pb_fuzzer {
ast_manager& m;
random_gen rand;
smt_params params;
smt::context ctx;
expr_ref_vector vars;
public:
pb_fuzzer(ast_manager& m): m(m), rand(0), ctx(m, params), vars(m) {
params.m_model = true;
unsigned N = 3;
for (unsigned i = 0; i < N; ++i) {
std::stringstream strm;
strm << "b" << i;
vars.push_back(m.mk_const(symbol(strm.str()), m.mk_bool_sort()));
std::cout << "(declare-const " << strm.str() << " Bool)\n";
}
}
void fuzz() {
enable_trace("pb");
unsigned nr = 0;
for (unsigned i = 0; i < 100000; ++i) {
fuzz_round(nr, 2);
}
}
private:
void add_ineq() {
pb_util pb(m);
expr_ref fml(m), tmp(m);
th_rewriter rw(m);
vector coeffs(vars.size());
expr_ref_vector args(vars);
while (true) {
rational k(rand(6));
for (unsigned i = 0; i < coeffs.size(); ++i) {
int v = 3 - rand(5);
coeffs[i] = rational(v);
if (coeffs[i].is_neg()) {
args[i] = m.mk_not(args[i].get());
coeffs[i].neg();
k += coeffs[i];
}
}
fml = pb.mk_ge(args.size(), coeffs.data(), args.data(), k);
rw(fml, tmp);
rw(tmp, tmp);
if (pb.is_ge(tmp)) {
fml = tmp;
break;
}
}
std::cout << "(assert " << fml << ")\n";
ctx.assert_expr(fml);
std::cout << ";asserted\n";
}
void fuzz_round(unsigned& num_rounds, unsigned lvl) {
unsigned num_rounds2 = 0;
lbool is_sat = l_true;
std::cout << "(push 1)\n";
ctx.push();
unsigned r = 0;
while (is_sat == l_true && r <= num_rounds + 1) {
add_ineq();
std::cout << "(check-sat)\n";
is_sat = ctx.check();
if (lvl > 0 && is_sat == l_true) {
fuzz_round(num_rounds2, lvl-1);
}
++r;
}
num_rounds = r;
std::cout << "; number of rounds: " << num_rounds << " level: " << lvl << "\n";
ctx.pop(1);
std::cout << "(pop 1)\n";
}
};
static void fuzz_pb()
{
ast_manager m;
reg_decl_plugins(m);
pb_fuzzer fuzzer(m);
fuzzer.fuzz();
}
void tst_theory_pb() {
fuzz_pb();
ast_manager m;
smt_params params;
params.m_model = true;
reg_decl_plugins(m);
expr_ref tmp(m);
enable_trace("pb");
for (unsigned N = 4; N < 11; ++N) {
for (unsigned i = 0; i < (1u << N); ++i) {
smt::literal_vector lits(N, smt::false_literal);
unsigned k = populate_literals(i, lits);
std::cout << "k:" << k << " " << N << "\n";
std::cout.flush();
TRACE("pb", tout << "k " << k << ": " << lits << "\n";);
{
smt::context ctx(m, params);
ctx.push();
smt::literal l = smt::theory_pb::assert_ge(ctx, k+1, lits.size(), lits.data());
if (l != smt::false_literal) {
ctx.assign(l, nullptr, false);
TRACE("pb", tout << "assign: " << l << "\n";
ctx.display(tout););
VERIFY(l_false == ctx.check());
}
ctx.pop(1);
}
{
smt::context ctx(m, params);
ctx.push();
smt::literal l = smt::theory_pb::assert_ge(ctx, k, lits.size(), lits.data());
ENSURE(l != smt::false_literal);
ctx.assign(l, nullptr, false);
TRACE("pb", ctx.display(tout););
VERIFY(l_true == ctx.check());
ctx.pop(1);
}
}
}
}