static
void nterm_check_and_process(Term lit, Mstate state)
{
  int pos;
  int id;
  int neg = NEGATED(lit);
  int eq = EQ_TERM(lit);
  int type = (neg && eq ? NEAR_ELIMINATION : NEAR_ASSIGNMENT);
  if (eq) {
    Term a0 = ARG(lit,0);
    Term a1 = ARG(lit,1);

    if (VARIABLE(a1) && nterm(a0, &pos, &id)) {
      insert_negprop_eq(lit, a0, VARNUM(a1), state);
      job_prepend(state, type, id, a0, a1, pos);
    }
    else if (VARIABLE(a0) && nterm(a1, &pos, &id)) {
      insert_negprop_eq(lit, a1, VARNUM(a0), state);
      job_prepend(state, type, id, a1, a0, pos);
    }
  }
  else if (nterm(lit, &pos, &id)) {
    insert_negprop_noneq(lit, state);
    job_prepend(state, NEAR_ASSIGNMENT, id, lit,
		(neg ? Domain[0] : Domain[1]), pos);
  }
}  /* nterm_check_and_process */
static
void process_clause(Mclause c, Mstate state)
{
  if (c->subsumed)
    return;
  else if (c->u.active == 0) {
    if (flag(Opt->trace))
      printf("\t\t\t\t\t** BACKUP **\n");
    state->ok = FALSE;
    return;
  }
  else if (c->u.active != 1)
    return;   /* nonunit, so do nothing */
  else {
    /* OK, we have a nonsubsumed unit. */
    Term lit, beta;
    BOOL negated, eq;
    int id;
    int i = 0;
    while (FALSE_TERM(LIT(c,i)))
      i++;
    
    lit = LIT(c,i);
    negated = NEGATED(lit);
    eq = EQ_TERM(lit);

#if 0
    printf("process_clause 1: ");
    p_matom(lit);
#endif

    if (!eq && eterm(lit, &id))
      beta = Domain[negated ? 0 : 1]; /* P(1,2,3) or ~P(1,2,3) */
    else if (eq && eterm(ARG(lit,0),&id) && VARIABLE(ARG(lit,1)))
      beta = ARG(lit,1);  /* f(1,2)=3 or f(1,2)!=3 */
    else if (eq && eterm(ARG(lit,1),&id) && VARIABLE(ARG(lit,0)))
      beta = ARG(lit,0);  /* 3=f(1,2) or 3!=f(1,2) */
    else {
      if (flag(Opt->negprop))
	/* If it is an nterm, index and insert into job list. */
	nterm_check_and_process(lit, state);
      return;  /* We cannot do anything else with the unit. */
    }

    if (eq && negated)
      new_elimination(id, beta, state);  /* f(1,2) != 3 */
    else
      new_assignment(id, beta, state);   /* f(1,2) = 3, P(0), ~P(0) */
  }
}  /* process_clause */
Beispiel #3
0
uint Synth::walk(DdNode *a_dd) {
    /**
    Walk given DdNode node (recursively).
    If a given node requires intermediate AND gates for its representation, the function adds them.
        Literal representing given input node is `not` added to the spec.

    :returns: literal representing input node
    **/

    // caching
    static hmap<DdNode*, uint> cache;
    {
        auto cached_lit = cache.find(Cudd_Regular(a_dd));
        if (cached_lit != cache.end())
            return Cudd_IsComplement(a_dd) ? NEGATED(cached_lit->second) : cached_lit->second;
    }
    // end of caching

    if (Cudd_IsConstant(a_dd))
        return (uint) (a_dd == cudd.bddOne().getNode());  // in aiger: 0 is False and 1 is True

    // get an index of the variable
    uint a_lit = aiger_by_cudd[Cudd_NodeReadIndex(a_dd)];

    DdNode *t_bdd = Cudd_T(a_dd);
    DdNode *e_bdd = Cudd_E(a_dd);

    uint t_lit = walk(t_bdd);
    uint e_lit = walk(e_bdd);

    // ite(a_bdd, then_bdd, else_bdd)
    // = a*then + !a*else
    // = !(!(a*then) * !(!a*else))
    // -> in general case we need 3 more ANDs

    uint a_t_lit = get_optimized_and_lit(a_lit, t_lit);

    uint na_e_lit = get_optimized_and_lit(NEGATED(a_lit), e_lit);

    uint n_a_t_lit = NEGATED(a_t_lit);
    uint n_na_e_lit = NEGATED(na_e_lit);

    uint and_lit = get_optimized_and_lit(n_a_t_lit, n_na_e_lit);

    uint res = NEGATED(and_lit);

    cache[Cudd_Regular(a_dd)] = res;

    if (Cudd_IsComplement(a_dd))
        res = NEGATED(res);

    return res;
}
void p_matom(Term atom)
{
  if (atom == NULL)
    printf("(NULL)");
  else if (!NEGATED(atom))
    fwrite_term(stdout, atom);
  else if (EQ_TERM(atom)){
    fwrite_term(stdout, ARG(atom,0));
    printf(" != ");
    fwrite_term(stdout, ARG(atom,1));
  }
  else {
    printf("~(");
    fwrite_term(stdout, atom);
    printf(")");
  }
  printf(".\n");
}  /* p_matom */
void p_mclause(Mclause c)
{
  int i;
  printf("numlits=%d, active=%ld, subsumed=%d: ",
	 c->numlits, c->u.active, c->subsumed);
  for (i = 0; i < c->numlits; i++) {
    Term atom = LIT(c,i);
    if (!NEGATED(atom))
      fwrite_term(stdout, atom);
    else {
      printf("~(");
      fwrite_term(stdout, atom);
      printf(")");
    }
    if (i < c->numlits-1)
      printf(" | ");
    else
      printf(".\n");
  }
}  /* p_mclause */