@@ -387,7 +387,8 @@ add_state_to_aiger (Btor *btor,
387
387
aiger *aig,
388
388
BoolectorNode *state,
389
389
BoolectorNode *next,
390
- BoolectorNode *init)
390
+ BoolectorNode *init,
391
+ std::vector<std::pair<uint64_t , uint64_t > > &init_constrains)
391
392
{
392
393
size_t nbits;
393
394
const char *sym;
@@ -414,18 +415,16 @@ add_state_to_aiger (Btor *btor,
414
415
415
416
for (size_t i = 0 ; i < nbits; ++i)
416
417
{
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
- }
423
418
sym = boolector_aig_get_symbol (amgr, state_bits[i]);
424
419
if (next_bits)
425
420
{
426
- reset_val = init_bits ? init_bits[i] : state_bits[i];
427
421
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
+ }
429
428
}
430
429
else
431
430
{
@@ -472,11 +471,23 @@ add_bad_to_aiger (Btor *btor,
472
471
boolector_aig_free_bits (amgr, bits, nbits);
473
472
}
474
473
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
+
475
485
static void
476
486
generate_aiger (Btor2Model &model, bool ascii_mode, bool ignore_error)
477
487
{
478
488
BoolectorAIGMgr *amgr;
479
489
aiger *aig;
490
+ std::vector<std::pair<uint64_t , uint64_t > > init_constrains;
480
491
481
492
amgr = boolector_aig_new (model.btor );
482
493
@@ -497,6 +508,7 @@ generate_aiger (Btor2Model &model, bool ascii_mode, bool ignore_error)
497
508
for (auto kv : model.init )
498
509
{
499
510
boolector_aig_bitblast (amgr, kv.second );
511
+ boolector_aig_visit (amgr, kv.second , aig_visitor, &aig_visitor_state);
500
512
}
501
513
502
514
for (auto kv : model.next )
@@ -512,7 +524,8 @@ generate_aiger (Btor2Model &model, bool ascii_mode, bool ignore_error)
512
524
aig,
513
525
kv.second ,
514
526
model.get_next (kv.first ),
515
- model.get_init (kv.first ));
527
+ model.get_init (kv.first ),
528
+ init_constrains);
516
529
}
517
530
518
531
for (BoolectorNode *n : model.constraints )
@@ -534,6 +547,17 @@ generate_aiger (Btor2Model &model, bool ascii_mode, bool ignore_error)
534
547
{
535
548
die (err);
536
549
}
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
+ }
537
561
538
562
aiger_write_to_file (
539
563
aig, ascii_mode ? aiger_ascii_mode : aiger_binary_mode, stdout);
0 commit comments