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 */
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 */