void Synth::model_to_aiger(const BDD &c_signal, const BDD &func) { /// Update AIGER spec with a definition of `c_signal` uint c_lit = aiger_by_cudd[c_signal.NodeReadIndex()]; string output_name = string(aiger_is_input(aiger_spec, c_lit)->name); // save the name before it is freed uint func_as_aiger_lit = walk(func.getNode()); aiger_redefine_input_as_and(aiger_spec, c_lit, func_as_aiger_lit, func_as_aiger_lit); if (print_full_model) aiger_add_output(aiger_spec, c_lit, output_name.c_str()); }
static void expand (simpaig * aig) { unsigned maxvar; simpaig_assign_indices (mgr, aig); maxvar = simpaig_max_index (mgr); aigs = calloc (maxvar + 1, sizeof aigs[0]); copyaig (aig); aiger_add_output (expansion, simpaig_unsigned_index (aig), 0); free (aigs); simpaig_reset_indices (mgr); free (buffer); }
int main (int argc, char ** argv) { const char * input, * output, * err; aiger_and * a; unsigned j; int i, ok; input = output = 0; for (i = 1; i < argc; i++) { if (!strcmp (argv[i], "-h")) { printf ("%s", USAGE); exit (0); } else if (!strcmp (argv[i], "-v")) verbose = 1; else if (!strcmp (argv[i], "-i")) ignore = 1; else if (!strcmp (argv[i], "-r")) reverse = 1; else if (argv[i][0] == '-') die ("invalid command line option '%s'", argv[i]); else if (output) die ("too many arguments"); else if (input) output = argv[i]; else input = argv[i]; } src = aiger_init (); if (input) { msg ("reading '%s'", input); err = aiger_open_and_read_from_file (src, input); } else { msg ("reading '<stdin>'"); err = aiger_read_from_file (src, stdin); } if (err) die ("read error: %s", err); msg ("read MILOA %u %u %u %u %u BCJF %u %u %u %u", src->maxvar, src->num_inputs, src->num_latches, src->num_outputs, src->num_ands, src->num_bad, src->num_constraints, src->num_justice, src->num_fairness); if (!ignore && src->num_justice) die ("will not ignore justice properties (use '-i')"); if (!ignore && src->num_fairness) die ("will not ignore fairness properties (use '-i')"); if (!reverse && src->num_outputs && !src->num_bad && !src->num_constraints && !src->num_justice && !src->num_fairness) die ("only outputs founds (use '-r' for reverse move)"); dst = aiger_init (); for (j = 0; j < src->num_inputs; j++) aiger_add_input (dst, src->inputs[j].lit, src->inputs[j].name); for (j = 0; j < src->num_latches; j++) { aiger_add_latch (dst, src->latches[j].lit, src->latches[j].next, src->latches[j].name); aiger_add_reset (dst, src->latches[j].lit, src->latches[j].reset); } for (j = 0; j < src->num_ands; j++) { a = src->ands + j; aiger_add_and (dst, a->lhs, a->rhs0, a->rhs1); } if (reverse) { for (j = 0; j < src->num_outputs; j++) aiger_add_bad (dst, src->outputs[j].lit, src->outputs[j].name); } else { for (j = 0; j < src->num_outputs; j++) aiger_add_output (dst, src->outputs[j].lit, src->outputs[j].name); if (src->num_bad && src->num_constraints) { if (src->num_latches) { latch = next (); valid = latch + 2*src->num_constraints; aiger_add_latch (dst, latch, aiger_not (valid), "AIGMOVE_INVALID_LATCH"); prev = aiger_not (latch); for (j = 0; j < src->num_constraints; j++) { unsigned tmp = latch + 2*(j+1); aiger_add_and (dst, tmp, prev, src->constraints[j].lit); prev = tmp; } assert (prev == valid); } else { valid = src->constraints[0].lit; for (j = 1; j < src->num_constraints; j++) { unsigned tmp = next (); aiger_add_and (dst, tmp, valid, src->constraints[j].lit); valid = tmp; } } for (j = 0; j < src->num_bad; j++) { bad = next (); aiger_add_and (dst, bad, valid, src->bad[j].lit); aiger_add_output (dst, bad, src->bad[j].name); } } else for (j = 0; j < src->num_bad; j++) aiger_add_output (dst, src->bad[j].lit, src->bad[j].name); } aiger_reset (src); msg ("write MILOA %u %u %u %u %u", dst->maxvar, dst->num_inputs, dst->num_latches, dst->num_outputs, dst->num_ands); if (output) { msg ("writing '%s'", output); ok = aiger_open_and_write_to_file (dst, output); } else { msg ("writing '<stdout>'", output); ok = aiger_write_to_file (dst, (isatty (1) ? aiger_ascii_mode : aiger_binary_mode), stdout); } if (!ok) die ("write error"); aiger_reset (dst); return 0; }
unsigned * aigfuzz_layers (aiger * model, aigfuzz_opts * opts) { unsigned j, k, lit, start, end, pos, * res; Layer * l, * m; AIG * a; aigfuzz_opt ("fuzzer layers"); depth = aigfuzz_pick (opts->large ? 50 : 2, opts->small ? 10 : 200); aigfuzz_opt ("depth %u", depth); layer = calloc (depth, sizeof *layer); width = aigfuzz_pick (opts->large ? 50 : 10, opts->small ? 20 : 200); aigfuzz_opt ("width %u", width); input_fraction = aigfuzz_pick (0, 20); aigfuzz_opt ("input fraction %u%%", input_fraction); latch_fraction = opts->combinational ? 0 : aigfuzz_pick (0, 100); aigfuzz_opt ("latch fraction %u%%", latch_fraction); lower_fraction = 10 * aigfuzz_pick (0, 5); aigfuzz_opt ("lower fraction %u%%", lower_fraction); monotonicity = aigfuzz_pick (0, 2) - 1; aigfuzz_opt ("monotonicity %d", monotonicity); for (l = layer; l < layer + depth; l++) { assert (10 <= width); if (monotonicity < 0 && l == layer + 1) l->M = aigfuzz_pick (layer[0].M, 2 * layer[0].M); else { l->M = aigfuzz_pick (10, 10 + width - 1); if (monotonicity > 0 && l > layer && l->M < l[-1].M) l->M = l[-1].M; else if (monotonicity < 0 && l > layer + 1 && l->M > l[-1].M) l->M = l[-1].M; } if (!I) l->I = l->M; else if (input_fraction) l->I = aigfuzz_pick (0, fraction (input_fraction, l->M)); if (latch_fraction) { l->L = aigfuzz_pick (0, fraction (latch_fraction, l->I)); l->I -= l->L; } l->A = l->M; l->A -= l->I; l->A -= l->L; M += l->M; I += l->I; L += l->L; A += l->A; l->aigs = calloc (l->M, sizeof *l->aigs); l->unused = calloc (l->M, sizeof *l->unused); l->O = l->M; } assert (M = I + L + A); lit = 0; for (l = layer; l < layer + depth; l++) for (j = 0; j < l->I; j++) l->aigs[j].lit = (lit += 2); assert (lit/2 == I); for (l = layer; l < layer + depth; l++) { start = l->I; end = start + l->L; for (j = start; j < end; j++) l->aigs[j].lit = (lit += 2); } assert (lit/2 == I + L); for (l = layer; l < layer + depth; l++) { start = l->I + l->L; end = start + l->A; assert (end == l->M); for (j = start; j < end; j++) l->aigs[j].lit = (lit += 2); } for (l = layer; l < layer + depth; l++) for (j = 0; j < l->M; j++) l->unused[j] = l->aigs[j].lit; assert (lit/2 == M); for (l = layer; l < layer + depth; l++) { start = l->I + l->L; end = start + l->A; assert (end == l->M); for (j = start; j < end; j++) { a = l->aigs + j; for (k = 0; k <= 1; k++) { m = l - 1; if (k) { while (m > layer && aigfuzz_pick (1, 100) <= lower_fraction) m--; } if (m->O > 0) { pos = aigfuzz_pick (0, m->O - 1); lit = m->unused[pos]; m->unused[pos] = m->unused[--m->O]; } else { pos = aigfuzz_pick (0, m->M - 1); lit = m->aigs[pos].lit; } if (aigfuzz_oneoutof (2)) lit++; if (k && a->child[0]/2 == lit/2) k--; else a->child[k] = lit; } lit = a->child[1]; if (a->child[0] < lit) { a->child[1] = a->child[0]; a->child[0] = lit; } assert (a->lit > a->child[0]); assert (a->child[0] > a->child[1]); } } for (l = layer + depth - 1; l>= layer; l--) { start = l->I; end = start + l->L; for (j = start; j < end; j++) { a = l->aigs + j; m = l + 1; if (m >= layer + depth) m -= depth; while (aigfuzz_oneoutof (2)) { m++; if (m >= layer + depth) m -= depth; } if (m->O > 0) { pos = aigfuzz_pick (0, m->O - 1); lit = m->unused[pos]; m->unused[pos] = m->unused[--m->O]; } else { pos = aigfuzz_pick (0, m->M - 1); lit = m->aigs[pos].lit; } if (aigfuzz_oneoutof (2)) lit++; a->next = lit; } } for (l = layer + depth - 1; l>= layer; l--) aigfuzz_msg (2, "layer[%u] MILOA %u %u %u %u %u", l-layer, l->M, l->I, l->L, l->O, l->A); for (l = layer; l < layer + depth; l++) for (j = 0; j < l->I; j++) aiger_add_input (model, l->aigs[j].lit, 0); for (l = layer; l < layer + depth; l++) { start = l->I; end = start + l->L; for (j = start; j < end; j++) { aiger_add_latch (model, l->aigs[j].lit, l->aigs[j].next, 0); if (opts->version < 2) continue; if (aigfuzz_pick (0, 1)) continue; aiger_add_reset (model, l->aigs[j].lit, aigfuzz_pick (0, 1) ? l->aigs[j].lit : 1); } } for (l = layer; l < layer + depth; l++) { start = l->I + l->L; end = start + l->A; assert (end == l->M); for (j = start; j < end; j++) { a = l->aigs + j; aiger_add_and (model, a->lit, a->child[0], a->child[1]); } } for (l = layer; l < layer + depth; l++) O += l->O; res = calloc (O + 1, sizeof *res); O = 0; for (l = layer; l < layer + depth; l++) for (j = 0; j < l->O; j++) { lit = l->unused[j]; if (aigfuzz_oneoutof (2)) lit ^= 1; res[O++] = lit; } res[O] = UINT_MAX; #if 0 if (opts->merge) { aigfuzz_msg (1, "merging %u unused outputs", O); unused = calloc (O, sizeof *unused); O = 0; for (l = layer; l < layer + depth; l++) for (j = 0; j < l->O; j++) unused[O++] = l->unused[j]; while (O > 1) { pos = aigfuzz_pick (0, O - 1); rhs0 = unused[pos]; unused[pos] = unused[--O]; if (aigfuzz_pick (7, 8) == 7) rhs0++; assert (O > 0); pos = aigfuzz_pick (0, O - 1); rhs1 = unused[pos]; if (aigfuzz_pick (11, 12) == 11) rhs1++; lhs = 2 * ++M; aiger_add_and (model, lhs, rhs0, rhs1); unused[pos] = lhs; } if (O == 1) { out = unused[0]; if (aigfuzz_pick (3, 4) == 3) out++; aiger_add_output (model, out, 0); } } else { for (l = layer; l < layer + depth; l++) for (j = 0; j < l->O; j++) { lit = l->unused[j]; if (aigfuzz_pick (17, 18) == 17) lit++; aiger_add_output (model, lit, 0); } } #endif for (l = layer; l < layer + depth; l++) { free (l->aigs); free (l->unused); } free (layer); return res; }