#include "ast/ast_pp.h"
#include "ast/ast_ll_pp.h"
#include "ast/reg_decl_plugins.h"
#include "ast/rewriter/bit_blaster/bit_blaster.h"
#include "model/model.h"
#include "model/model_evaluator.h"
void mk_bits(ast_manager & m, char const * prefix, unsigned sz, expr_ref_vector & r) {
sort_ref b(m);
b = m.mk_bool_sort();
for (unsigned i = 0; i < sz; ++i) {
std::stringstream ous;
ous << prefix << i << ".smt2";
r.push_back(m.mk_const(symbol(ous.str()), b));
}
}
void display(std::ostream & out, expr_ref_vector & r, bool ll=true) {
for (unsigned i = 0; i < r.size(); ++i) {
out << "bit " << i << ":\n";
if (ll)
ast_ll_pp(out, r.get_manager(), r.get(i));
else
out << mk_pp(r.get(i), r.get_manager()) << "\n";
}
}
static unsigned to_int(model_core & mdl, expr_ref_vector & out) {
ENSURE(out.size() <= sizeof(unsigned) * 8);
ast_manager & m = mdl.get_manager();
model_evaluator eval(mdl);
expr_ref bit(m);
unsigned actual = 0;
for (unsigned i = 0; i < out.size(); ++i) {
eval(out.get(i), bit);
if (m.is_true(bit))
actual |= 1 << i;
else
ENSURE(m.is_false(bit));
}
return actual;
}
#define ENSURE_INT(mdl, out, expected) \
do { \
unsigned actual = to_int(mdl, out); \
TRACE(bit_blaster, \
display(tout, out); \
tout << "expected=" << (expected) << ", actual=" << actual << "\n"; \
); \
ENSURE(actual == (expected)); \
} while (0)
void tst_adder(ast_manager & m, bit_blaster & blaster) {
model mdl(m);
expr_ref_vector c(m);
app_ref b1(m.mk_const("b1", m.mk_bool_sort()), m);
app_ref b2(m.mk_const("b2", m.mk_bool_sort()), m);
expr_ref not_b1(m.mk_not(b1), m);
{
expr * const a[] = { b1, b1, b1 };
expr * const b[] = { m.mk_false(), m.mk_true(), m.mk_true() };
c.reset();
blaster.mk_adder(3, a, b, c);
}
mdl.register_decl(b1->get_decl(), m.mk_false());
ENSURE_INT(mdl, c, 6);
mdl.register_decl(b1->get_decl(), m.mk_true());
ENSURE_INT(mdl, c, 5);
{
expr * const a[] = { m.mk_false(), m.mk_true(), m.mk_true() };
expr * const b[] = { b1, not_b1, m.mk_false() };
c.reset();
blaster.mk_adder(3, a, b, c);
}
mdl.register_decl(b1->get_decl(), m.mk_false());
ENSURE_INT(mdl, c, 0);
mdl.register_decl(b1->get_decl(), m.mk_true());
ENSURE_INT(mdl, c, 7);
{
expr * const a[] = { b1, b2, m.mk_true() };
expr * const b[] = { b1, not_b1, m.mk_false() };
c.reset();
blaster.mk_adder(3, a, b, c);
}
mdl.register_decl(b1->get_decl(), m.mk_false());
mdl.register_decl(b2->get_decl(), m.mk_false());
ENSURE_INT(mdl, c, 6);
mdl.register_decl(b1->get_decl(), m.mk_false());
mdl.register_decl(b2->get_decl(), m.mk_true());
ENSURE_INT(mdl, c, 0);
mdl.register_decl(b1->get_decl(), m.mk_true());
mdl.register_decl(b2->get_decl(), m.mk_false());
ENSURE_INT(mdl, c, 6);
mdl.register_decl(b1->get_decl(), m.mk_true());
mdl.register_decl(b2->get_decl(), m.mk_true());
ENSURE_INT(mdl, c, 0); }
void tst_multiplier(ast_manager & m, bit_blaster & blaster) {
model mdl(m);
expr_ref_vector c(m);
app_ref b1(m.mk_const("b1", m.mk_bool_sort()), m);
app_ref b2(m.mk_const("b2", m.mk_bool_sort()), m);
expr_ref not_b1(m.mk_not(b1), m);
{
expr * const a[] = { b1, b1, b1 };
expr * const b[] = { m.mk_false(), m.mk_true(), m.mk_true() };
c.reset();
blaster.mk_multiplier(3, a, b, c);
}
mdl.register_decl(b1->get_decl(), m.mk_false());
ENSURE_INT(mdl, c, 0);
mdl.register_decl(b1->get_decl(), m.mk_true());
ENSURE_INT(mdl, c, 2);
{
expr * const a[] = { m.mk_false(), m.mk_true(), m.mk_true() };
expr * const b[] = { b1, not_b1, m.mk_false() };
c.reset();
blaster.mk_multiplier(3, a, b, c);
}
mdl.register_decl(b1->get_decl(), m.mk_false());
ENSURE_INT(mdl, c, 4);
mdl.register_decl(b1->get_decl(), m.mk_true());
ENSURE_INT(mdl, c, 6);
{
expr * const a[] = { b1, b2, m.mk_true() };
expr * const b[] = { b1, not_b1, m.mk_false() };
c.reset();
blaster.mk_multiplier(3, a, b, c);
}
mdl.register_decl(b1->get_decl(), m.mk_false());
mdl.register_decl(b2->get_decl(), m.mk_false());
ENSURE_INT(mdl, c, 0);
mdl.register_decl(b1->get_decl(), m.mk_false());
mdl.register_decl(b2->get_decl(), m.mk_true());
ENSURE_INT(mdl, c, 4);
mdl.register_decl(b1->get_decl(), m.mk_true());
mdl.register_decl(b2->get_decl(), m.mk_false());
ENSURE_INT(mdl, c, 5);
mdl.register_decl(b1->get_decl(), m.mk_true());
mdl.register_decl(b2->get_decl(), m.mk_true());
ENSURE_INT(mdl, c, 7); }
void tst_le(ast_manager & m, unsigned sz) {
}
void tst_eqs(ast_manager & m, unsigned sz) {
}
void tst_sh(ast_manager & m, unsigned sz) {
}
void tst_bit_blaster() {
ast_manager m;
reg_decl_plugins(m);
bit_blaster_params params;
bit_blaster blaster(m, params);
tst_adder(m, blaster);
tst_multiplier(m, blaster);
tst_le(m, 4);
tst_eqs(m, 8);
tst_sh(m, 4);
}