Exemplo n.º 1
0
static void
copyaig (simpaig * aig)
{
  LatchOrInput *input;
  simpaig *c0, *c1;
  const char *name;
  unsigned idx;
  int slice;

  assert (aig);

  aig = simpaig_strip (aig);
  idx = simpaig_index (aig);
  if (!idx || aigs[idx])
    return;

  aigs[idx] = aig;
  if (simpaig_isand (aig))
    {
      c0 = simpaig_child (aig, 0);
      c1 = simpaig_child (aig, 1);
      copyaig (c0);
      copyaig (c1);
      aiger_add_and (expansion,
		     2 * idx,
		     simpaig_unsigned_index (c0),
		     simpaig_unsigned_index (c1));
    }
  else
    {
      name = 0;
      if (!strip)
	{
	  input = simpaig_isvar (aig);
	  assert (input);
	  slice = simpaig_slice (aig);

	  name = next_symbol (input->idx, slice);
	}

      aiger_add_input (expansion, 2 * idx, name);
    }
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
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;
}