Skip to content

Commit 6f0bbf4

Browse files
authored
support arbitrary initialization functions in btor2aiger (#27)
Signed-off-by: Yuheng Su <[email protected]>
1 parent 44bcadb commit 6f0bbf4

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
*.o
22
makefile
33
catbtor
4+
deps/
5+
build/

src/btor2aiger.cpp

+34-10
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,8 @@ add_state_to_aiger (Btor *btor,
387387
aiger *aig,
388388
BoolectorNode *state,
389389
BoolectorNode *next,
390-
BoolectorNode *init)
390+
BoolectorNode *init,
391+
std::vector<std::pair<uint64_t, uint64_t> > &init_constrains)
391392
{
392393
size_t nbits;
393394
const char *sym;
@@ -414,18 +415,16 @@ add_state_to_aiger (Btor *btor,
414415

415416
for (size_t i = 0; i < nbits; ++i)
416417
{
417-
if (init_bits && init_bits[i] != 0 && init_bits[i] != 1)
418-
{
419-
/* Note: BTOR2 supports arbitrary initialization functions, but AIGER
420-
* only supports 0/1/undefined. */
421-
die ("Found non-constant initialization");
422-
}
423418
sym = boolector_aig_get_symbol (amgr, state_bits[i]);
424419
if (next_bits)
425420
{
426-
reset_val = init_bits ? init_bits[i] : state_bits[i];
427421
aiger_add_latch (aig, state_bits[i], next_bits[i], sym);
428-
aiger_add_reset (aig, state_bits[i], reset_val);
422+
if (!(init_bits && init_bits[i] != 0 && init_bits[i] != 1)) {
423+
reset_val = init_bits ? init_bits[i] : state_bits[i];
424+
aiger_add_reset (aig, state_bits[i], reset_val);
425+
} else {
426+
init_constrains.push_back(std::make_pair(state_bits[i], init_bits[i]));
427+
}
429428
}
430429
else
431430
{
@@ -472,11 +471,23 @@ add_bad_to_aiger (Btor *btor,
472471
boolector_aig_free_bits (amgr, bits, nbits);
473472
}
474473

474+
unsigned conj(aiger *aig, unsigned x, unsigned y) {
475+
const unsigned new_var = (aig->maxvar + 1) * 2;
476+
aiger_add_and(aig, new_var, x, y);
477+
return new_var;
478+
};
479+
480+
unsigned eq(aiger *aig, unsigned x, unsigned y) {
481+
return aiger_not(conj(aig, aiger_not(conj(aig, x, y)),
482+
aiger_not(conj(aig, aiger_not(x), aiger_not(y)))));
483+
}
484+
475485
static void
476486
generate_aiger (Btor2Model &model, bool ascii_mode, bool ignore_error)
477487
{
478488
BoolectorAIGMgr *amgr;
479489
aiger *aig;
490+
std::vector<std::pair<uint64_t, uint64_t> > init_constrains;
480491

481492
amgr = boolector_aig_new (model.btor);
482493

@@ -497,6 +508,7 @@ generate_aiger (Btor2Model &model, bool ascii_mode, bool ignore_error)
497508
for (auto kv : model.init)
498509
{
499510
boolector_aig_bitblast (amgr, kv.second);
511+
boolector_aig_visit (amgr, kv.second, aig_visitor, &aig_visitor_state);
500512
}
501513

502514
for (auto kv : model.next)
@@ -512,7 +524,8 @@ generate_aiger (Btor2Model &model, bool ascii_mode, bool ignore_error)
512524
aig,
513525
kv.second,
514526
model.get_next (kv.first),
515-
model.get_init (kv.first));
527+
model.get_init (kv.first),
528+
init_constrains);
516529
}
517530

518531
for (BoolectorNode *n : model.constraints)
@@ -534,6 +547,17 @@ generate_aiger (Btor2Model &model, bool ascii_mode, bool ignore_error)
534547
{
535548
die (err);
536549
}
550+
551+
if (!init_constrains.empty()) {
552+
unsigned init_latch = (aig->maxvar + 1) * 2;
553+
aiger_add_latch(aig, init_latch, 0, "init latch");
554+
aiger_add_reset(aig, init_latch, 1);
555+
for (unsigned i = 0; i < init_constrains.size(); ++i) {
556+
unsigned init_eq = eq(aig, init_constrains[i].first, init_constrains[i].second);
557+
unsigned init = aiger_not(conj(aig, init_latch, aiger_not(init_eq)));
558+
aiger_add_constraint(aig, init, 0);
559+
}
560+
}
537561

538562
aiger_write_to_file (
539563
aig, ascii_mode ? aiger_ascii_mode : aiger_binary_mode, stdout);

0 commit comments

Comments
 (0)