int removeTautologies(Array<BinaryTree_AVL<Clause> > &clarray, unsigned int curdepth) { // list of tautologies to remove List<Clause> clausesToRemove; // check if these tests should be run if (!tautologytest) return(OK); // scan each equivalence set for tautologies BinaryTree_AVL_Iterator_InOrder<Clause> clIter(clarray[curdepth]); for ( ; !clIter.done(); clIter++) { // check each member for being a tautolgy Clause clause(clIter()); statistics[AttemptedTautologyTests] += 1; totalstatistics[TotalAttemptedTautologyTests] += 1; if (tautology(clause) == OK) { // we have a tautology, remove it. statistics[TautologiesRemoved] += 1; totalstatistics[TotalTautologiesRemoved] += 1; if (clausesToRemove.insert(clause) != OK) { ERROR("insert failed.", errno); return(NOTOK); } } } // remove any clauses ListIterator<Clause> cltrIter(clausesToRemove); for ( ; !cltrIter.done(); cltrIter++) { Clause clause(cltrIter()); int status = clarray[curdepth].remove(clause); if (status != OK && status != NOMATCH) { ERROR("remove failed.", errno); return(NOTOK); } } // all done return(OK); }
QueryPtr DisjunctionMaxQuery::rewrite(IndexReaderPtr reader) { int32_t numDisjunctions = disjuncts.size(); if (numDisjunctions == 1) { QueryPtr singleton(disjuncts[0]); QueryPtr result(singleton->rewrite(reader)); if (getBoost() != 1.0) { if (result == singleton) result = boost::dynamic_pointer_cast<Query>(result->clone()); result->setBoost(getBoost() * result->getBoost()); } return result; } DisjunctionMaxQueryPtr clone; for (int32_t i = 0; i < numDisjunctions; ++i) { QueryPtr clause(disjuncts[i]); QueryPtr rewrite(clause->rewrite(reader)); if (rewrite != clause) { if (!clone) clone = boost::dynamic_pointer_cast<DisjunctionMaxQuery>(this->clone()); clone->disjuncts[i] = rewrite; } } return clone ? clone : shared_from_this(); }
int runprover() { // check if anything to prove if (clauses.isEmpty()) { ERROR("clauses program is empty.", EINVAL); return(NOTOK); } // list of clauses List<Clause> clauselist; // convert strings to actual clauses for proving ListIterator<List<String > > clausesIter(clauses); for (int icl=1; !clausesIter.done(); clausesIter++, icl++) { Clause clause(clausesIter()); if (clauselist.insertAtEnd(clause) != OK) return(NOTOK); } // list clauses cout << "===============================================" << endl; cout << "clauses of literals are: " << endl; ListIterator<Clause> clIter(clauselist); for ( ; !clIter.done(); clIter++) { cout << "clause is ... " << endl << clIter() << endl; } cout << "===============================================" << endl; // run real prover on list of clauses return(runprover(clauselist)); }
QString GlobalDBStorage::GetWhereClause(MSqlBindings &bindings) const { QString valueTag(":WHEREVALUE"); QString clause("value = " + valueTag); bindings.insert(valueTag, settingname); return clause; }
QString SimpleDBStorage::setClause(MSqlBindings &bindings) { QString tagname(":SET" + column.upper()); QString clause(column + " = " + tagname); bindings.insert(tagname, setting->getValue().utf8()); return clause; }
QString GlobalDBStorage::whereClause(MSqlBindings &bindings) { QString valueTag(":WHEREVALUE"); QString clause("value = " + valueTag); bindings.insert(valueTag, setting->getName()); return clause; }
QString SimpleDBStorage::GetSetClause(MSqlBindings &bindings) const { QString tagname(":SET" + GetColumnName().toUpper()); QString clause(GetColumnName() + " = " + tagname); bindings.insert(tagname, user->GetDBValue()); return clause; }
void extract_clauses_and_dependencies(goal_ref const& g, expr_ref_vector& clauses, ptr_vector<expr>& assumptions, expr2expr_map& bool2dep, ref<filter_model_converter>& fmc) { expr2expr_map dep2bool; ptr_vector<expr> deps; ast_manager& m = g->m(); expr_ref_vector clause(m); unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { expr * f = g->form(i); expr_dependency * d = g->dep(i); if (d == 0 || !g->unsat_core_enabled()) { clauses.push_back(f); } else { // create clause (not d1 \/ ... \/ not dn \/ f) when the d's are the assumptions/dependencies of f. clause.reset(); clause.push_back(f); deps.reset(); m.linearize(d, deps); SASSERT(!deps.empty()); // d != 0, then deps must not be empty ptr_vector<expr>::iterator it = deps.begin(); ptr_vector<expr>::iterator end = deps.end(); for (; it != end; ++it) { expr * d = *it; if (is_uninterp_const(d) && m.is_bool(d)) { // no need to create a fresh boolean variable for d if (!bool2dep.contains(d)) { assumptions.push_back(d); bool2dep.insert(d, d); } clause.push_back(m.mk_not(d)); } else { // must normalize assumption expr * b = 0; if (!dep2bool.find(d, b)) { b = m.mk_fresh_const(0, m.mk_bool_sort()); dep2bool.insert(d, b); bool2dep.insert(b, d); assumptions.push_back(b); if (!fmc) { fmc = alloc(filter_model_converter, m); } fmc->insert(to_app(b)->get_decl()); } clause.push_back(m.mk_not(b)); } } SASSERT(clause.size() > 1); expr_ref cls(m); cls = mk_or(m, clause.size(), clause.c_ptr()); clauses.push_back(cls); } } }
QString GlobalDBStorage::GetSetClause(MSqlBindings &bindings) const { QString valueTag(":SETVALUE"); QString dataTag(":SETDATA"); QString clause("value = " + valueTag + ", data = " + dataTag); bindings.insert(valueTag, settingname); bindings.insert(dataTag, user->GetDBValue()); return clause; }
QString GlobalDBStorage::setClause(MSqlBindings &bindings) { QString valueTag(":SETVALUE"); QString dataTag(":SETDATA"); QString clause("value = " + valueTag + ", data = " + dataTag); bindings.insert(valueTag, setting->getName()); bindings.insert(dataTag, setting->getValue().utf8()); return clause; }
int removeSubsumed(Array<BinaryTree_AVL<Clause> > &clarray, unsigned int curdepth) { // list of tautologies to remove List<Clause> clausesToRemove; // check if these tests should be run if (!subsumptiontest) return(OK); // check if any clause at the current depth is subsumed // by a clause at a lower level. // BinaryTree_AVL_Iterator_InOrder<Clause> cdIter(clarray[curdepth]); for ( ; !cdIter.done(); cdIter++) { // check if the current clause is subsumed for (int idepth = 0; idepth < curdepth; idepth++) { // get previous depth clauses BinaryTree_AVL_Iterator_InOrder<Clause> idIter(clarray[idepth]); for ( ; !idIter.done(); idIter++) { // check if a clause is a subset of // another. comparison is done by // comparing equivalent sets. // int status = removedSubsumed(idIter(), cdIter(), clausesToRemove); if (status != OK) return(status); } } } // remove any clauses ListIterator<Clause> cltrIter(clausesToRemove); for ( ; !cltrIter.done(); cltrIter++) { Clause clause(cltrIter()); int status = clarray[curdepth].remove(clause); if (status != OK && status != NOMATCH) { ERROR("remove failed.", errno); return(NOTOK); } } // all done return(OK); }
SpanOrQuery::SpanOrQuery(Collection<SpanQueryPtr> clauses) { // copy clauses array into an ArrayList this->clauses = Collection<SpanQueryPtr>::newInstance(); for (int32_t i = 0; i < clauses.size(); ++i) { SpanQueryPtr clause(clauses[i]); if (i == 0) { // check field field = clause->getField(); } else if (clause->getField() != field) { boost::throw_exception(IllegalArgumentException(L"Clauses must have same field.")); } this->clauses.add(clause); } }
QString HostDBStorage::setClause(MSqlBindings &bindings) { QString valueTag(":SETVALUE"); QString dataTag(":SETDATA"); QString hostnameTag(":SETHOSTNAME"); QString clause("value = " + valueTag + ", data = " + dataTag + ", hostname = " + hostnameTag); bindings.insert(valueTag, setting->getName()); bindings.insert(dataTag, setting->getValue().utf8()); bindings.insert(hostnameTag, gContext->GetHostName()); return clause; }
QString HostDBStorage::GetSetClause(MSqlBindings &bindings) const { QString valueTag(":SETVALUE"); QString dataTag(":SETDATA"); QString hostnameTag(":SETHOSTNAME"); QString clause("value = " + valueTag + ", data = " + dataTag + ", hostname = " + hostnameTag); bindings.insert(valueTag, settingname); bindings.insert(dataTag, user->GetDBValue()); bindings.insert(hostnameTag, MythDB::getMythDB()->GetHostName()); return clause; }
int removeSubsumed(Array<OrderedSet<Clause> > &clarray, unsigned int curdepth) { // list of tautologies to remove List<Clause> clausesToRemove; // check if any clause at the current depth is subsumed // by a clause at a lower level. // OrderedSetIterator<Clause> cdIter(clarray[curdepth]); for ( ; !cdIter.done(); cdIter++) { // check if the current clause is subsumed for (int idepth = 0; idepth <= curdepth; idepth++) { // get previous depth clauses OrderedSetIterator<Clause> idIter(clarray[idepth]); for ( ; !idIter.done(); idIter++) { // check if a clause is a subset of // another. comparison is done // comparing equivalent sets. // if (subset(idIter.key(), cdIter.key()) != OK) continue; // check each set for subsumed clauses int status = removedSubsumed(idIter.data(), cdIter.data(), clausesToRemove); if (status != OK) return(status); } } } // remove any clauses ListIterator<Clause> cltrIter(clausesToRemove); for ( ; !cltrIter.done(); cltrIter++) { Clause clause(cltrIter()); if (clarray[curdepth].remove(clause) != OK) return(NOTOK); } // all done return(OK); }
// remove tautologies int removeTautologies(Array<OrderedSet<Clause> > &clarray, unsigned int curdepth) { // list of tautologies to remove List<Clause> clausesToRemove; // scan each equivalence set for tautologies OrderedSetIterator<Clause> clIter(clarray[curdepth]); for ( ; !clIter.done(); clIter++) { // check each member in an equivalence set. ListIterator<Clause> dataIter(clIter.data()); for ( ; !dataIter.done(); dataIter++) { Clause clause(dataIter()); if (tautology(clause) == OK) { // we have a tautology, remove it. if (clausesToRemove.insert(clause) != OK) return(NOTOK); } } } // remove any clauses ListIterator<Clause> cltrIter(clausesToRemove); for ( ; !cltrIter.done(); cltrIter++) { Clause clause(cltrIter()); if (clarray[curdepth].remove(clause) != OK) return(NOTOK); } // all done return(OK); }
QString HostDBStorage::GetWhereClause(MSqlBindings &bindings) const { /* Returns a where clause of the form: * "value = :VALUE AND hostname = :HOSTNAME" * The necessary bindings are added to the MSQLBindings& */ QString valueTag(":WHEREVALUE"); QString hostnameTag(":WHEREHOSTNAME"); QString clause("value = " + valueTag + " AND hostname = " + hostnameTag); bindings.insert(valueTag, settingname); bindings.insert(hostnameTag, MythDB::getMythDB()->GetHostName()); return clause; }
CryptoMinisatSolver::CryptoMinisatSolver(StatisticsRegistry* registry, const std::string& name) : d_solver(new CMSat::SATSolver()) , d_numVariables(0) , d_okay(true) , d_statistics(registry, name) { d_true = newVar(); d_false = newVar(); std::vector<CMSat::Lit> clause(1); clause[0] = CMSat::Lit(d_true, false); d_solver->add_clause(clause); clause[0] = CMSat::Lit(d_false, true); d_solver->add_clause(clause); }
bool CSentence::BuildInitialClauses() { CClauseCollection::Clear(); IsValid(); m_bFirstInPairFound = false; int iFirstWord, iLastWord; iFirstWord = 0; int iStartSearch; int iPunctSignsCount = 0; for(int WordNo = 0 ; WordNo < m_Words.size(); WordNo = iStartSearch) { int iNextPunctCount = 0; if ( ((iLastWord = IsClauseBorder(WordNo, iStartSearch,iNextPunctCount, iFirstWord)) != -1) && (iLastWord >= iFirstWord) ) { if( m_pSyntaxOptions->m_KillHomonymsMode != DontKillHomonyms ) SolveAmbiguityUsingRuleForTwoPredicates(iFirstWord,iLastWord); //creating clause CClause clause(this, iFirstWord,iLastWord); //assigning clause type InitClauseType(clause); int debug = clause.m_vectorTypes.size(); clause.m_iPunctSignsCount = iPunctSignsCount; iPunctSignsCount = iNextPunctCount; InitConjunctions(&clause); AddClause(clause); iFirstWord = iLastWord + 1; } } return true; }
void Z3_API Z3_block_literals(Z3_context c, Z3_literals lbls) { Z3_TRY; LOG_Z3_block_literals(c, lbls); RESET_ERROR_CODE(); labels* _lbls = reinterpret_cast<labels*>(lbls); ast_manager& m = mk_c(c)->m(); expr_ref_vector lits(m); for (unsigned i = 0; i < _lbls->size(); ++i) { if ((*_lbls)[i].is_enabled()) { lits.push_back(m.mk_not((*_lbls)[i].get_literal())); } } expr_ref clause(m); clause = m.mk_or(lits.size(), lits.c_ptr()); mk_c(c)->save_ast_trail(clause.get()); mk_c(c)->assert_cnstr(clause.get()); Z3_CATCH; }
QueryPtr SpanOrQuery::rewrite(const IndexReaderPtr& reader) { SpanOrQueryPtr clone; for (int32_t i = 0; i < clauses.size(); ++i) { SpanQueryPtr clause(clauses[i]); SpanQueryPtr query(boost::dynamic_pointer_cast<SpanQuery>(clause->rewrite(reader))); if (query != clause) { // clause rewrote: must clone if (!clone) { clone = boost::dynamic_pointer_cast<SpanOrQuery>(this->clone()); } clone->clauses[i] = query; } } if (clone) { return clone; // some clauses rewrote } else { return shared_from_this(); // no clauses rewrote } }
int initialRemoveSubsumed(Array<BinaryTree_AVL<Clause> > &clarray, unsigned int curdepth) { List<Clause> clausesToRemove; // check if these tests should be run if (!subsumptiontest) return(OK); // check if current depth is empty if (clarray[curdepth].isEmpty()) return(OK); // check for subsumed clauses BinaryTree_AVL_Iterator_InOrder<Clause> cdIter1(clarray[curdepth]); for ( ; !cdIter1.done(); cdIter1++) { BinaryTree_AVL_Iterator_InOrder<Clause> cdIter2(cdIter1); for (cdIter2++; !cdIter2.done(); cdIter2++) { int status = removedSubsumed( cdIter1(), cdIter2(), clausesToRemove); if (status != OK) return(status); } } // remove any clauses ListIterator<Clause> cltrIter(clausesToRemove); for ( ; !cltrIter.done(); cltrIter++) { Clause clause(cltrIter()); int status = clarray[curdepth].remove(clause); if (status != OK && status != NOMATCH) { ERROR("remove failed.", errno); return(NOTOK); } } // all done return(OK); }
static std::vector<planner::MergeJoinPlan::JoinClause> BuildMergeJoinClauses( const MergeJoinClause join_clauses, const int num_clauses) { MergeJoinClause join_clause = join_clauses; expression::AbstractExpression *left = nullptr; expression::AbstractExpression *right = nullptr; std::vector<planner::MergeJoinPlan::JoinClause> clauses; LOG_TRACE("Mapping merge join clauses of size %d", num_clauses); for (int i = 0; i < num_clauses; ++i, ++join_clause) { left = ExprTransformer::TransformExpr(join_clause->lexpr); right = ExprTransformer::TransformExpr(join_clause->rexpr); planner::MergeJoinPlan::JoinClause clause(left, right, join_clause->ssup.ssup_reverse); LOG_TRACE("left: %s", clause.left_->Debug(" ").c_str()); LOG_TRACE("right: %s", clause.right_->Debug(" ").c_str()); clauses.push_back(std::move(clause)); } LOG_TRACE("Build join clauses of size %lu", clauses.size()); return clauses; }
void qbf_bdd_coret::lcnf(const bvt &bv) { bvt new_bv; if(process_clause(bv, new_bv)) return; BDD clause(bdd_manager->bddZero()); for(unsigned long i=0; i<new_bv.size(); i++) { literalt l=new_bv[i]; BDD v(*bdd_variable_map[l.var_no()]); if(l.sign()) v = ~v; clause |= v; } *matrix &= clause; }
pair<clause,int> SMTSolver_eq::diagnose_conflict(int conflict_dec_index) { assert(settings_s.smte_s); if(settings_s.disable_smt_cl_s) { int bt_level = solver->curr_level; OUTDEBUG(fprintf(stderr, "\tShould backtrack until level %d (last bet) inclusively.\n", bt_level)); return make_pair(clause(-1), bt_level); } decision conflict_dec = solver->decision_stack[conflict_dec_index]; smt_literal_eq* corresponding_lit = (smt_literal_eq*)solver->dpll_to_smt[abs(conflict_dec.dec)]; OUTDEBUG(fprintf(stderr, "\t[SMT]Diagnosing conflict because of %d (%s)\n", conflict_dec.dec, corresponding_lit->to_str().c_str())); int s1 = min(corresponding_lit->left, corresponding_lit->right); int s2 = max(corresponding_lit->left, corresponding_lit->right); OUTDEBUG(fprintf(stderr, "\t[SMT]Path from %d to %d: \n", s1, s2)); map<int,int> succ; dfs_enumerate_paths(s1, s2, succ); int curr = s1; clause c(solver->formula.size()); int bt_level = 0; int uip_like = solver->decision_stack.size()-1; while(curr != s2) { assert(edge[curr][succ[curr]] != conflict_dec_index); if(edge[curr][succ[curr]] != uip_like) bt_level = max(bt_level, solver->decision_stack[edge[curr][succ[curr]]].level); if(solver->decision_stack[edge[curr][succ[curr]]].level != -1) { c.literal.push_back(-solver->decision_stack[edge[curr][succ[curr]]].dec); c.assoc_lit[-solver->decision_stack[edge[curr][succ[curr]]].dec] = true; } OUTDEBUG(fprintf(stderr, "\t\t%d %d, dec: %d lvl: %d\n", curr, succ[curr], solver->decision_stack[edge[curr][succ[curr]]].dec, solver->decision_stack[edge[curr][succ[curr]]].level)); curr = succ[curr]; } OUTDEBUG(fprintf(stderr, "\n")); if(solver->decision_stack[conflict_dec_index].level != -1) { c.literal.push_back(-solver->decision_stack[conflict_dec_index].dec); c.assoc_lit[-solver->decision_stack[conflict_dec_index].dec] = true; } if(conflict_dec_index != uip_like) bt_level = max(bt_level, solver->decision_stack[conflict_dec_index].level); if(c.literal.size() != 1 && settings_s.wl_s) { c.triggers.insert(-solver->decision_stack[uip_like].dec); for(int i = uip_like-1 ; i >= 0 ; i--) if(c.assoc_lit.find(-solver->decision_stack[i].dec) != c.assoc_lit.end()) { c.triggers.insert(-solver->decision_stack[i].dec); break; } } OUTDEBUG(fprintf(stderr, "\t[SMT]Learning %s\n", c.to_str().c_str())); OUTDEBUG(fprintf(stderr, "\t[SMT]Backtracking to %d\n", bt_level)); return make_pair(c,bt_level); }
int* Parser::parse_clause() { eatws(); return clause(); }
// run provers int runprover(List<Clause> &clist) { // track current depth in proof unsigned int currentDepth = 0; // array of clauses for each depth Array<OrderedSet<Clause> > clausesArray(maxdepth+1); ListIterator<Clause> clIter(clist); for ( ; !clIter.done(); clIter++) { // insert clauses at current deph Clause clause(clIter()); clause.setDepth(currentDepth); clause.setNumber(nextClause++); if (clausesArray[currentDepth].insert(clause) != OK) return(NOTOK); } // filter clauses if (removeTautologies(clausesArray, currentDepth) != OK) return(NOTOK); if (removeSubsumed(clausesArray, currentDepth) != OK) return(NOTOK); // start breadth-first resolution process int clausesAdded = 1; for ( ; currentDepth <= maxdepth && clausesAdded; currentDepth++) { // reset clauses-added to false. it is reset to true // by resolveClauses if any clauses are added. // clausesAdded = 0; // resolve clauses at each level clausesAdded = 0; int status = resolveDepth(clausesArray, clausesAdded, currentDepth); switch (status) { case OK: case NOMATCH: case CONTINUE: // continue to next depth break; case VALID: // valid program cout << "VALID program." << endl; return(VALID); case INVALID: // invalid program cout << "INVALID program." << endl; return(INVALID); default: // some type of error cout << "ERROR from resolveDepth." << endl; return(status); } // remove redundant clauses if (clausesAdded) { if (removeTautologies( clausesArray, currentDepth+1) != OK) return(NOTOK); if (removeSubsumed( clausesArray, currentDepth+1) != OK) return(NOTOK); } } // all done if (currentDepth > maxdepth) { return(NOTPROVEN); } else if (!clausesAdded) { return(INVALID); } else { return(NOTOK); } }
// check if a clause is a tautology int tautology(const Clause &c) { // copy clause Clause clause(c); // check if the clause is positive, negative or mixed if (clause.getType() != Clause::Mixed) { // can not be a tautology return(NOMATCH); } // we have a mixed clause; it contains atoms and // negated atoms. check if A and ~A both occur // in the clause, then we have a tautology. // // check for tautologies. these comparisons are done // without the use of an index. this means that // we will use the comparison functions eq, ne, lt, le, // gt, ge, instead of the operator versions, ==, !=, etc. // PositiveClauseIterator posIter(c); NegativeClauseIterator negIter(c); while (!posIter.done() && !negIter.done()) { if (posIter().lt(~negIter())) { posIter++; } else if (posIter().gt(~negIter())) { negIter++; } else { // get positive literals in equivalence class Literal plit = posIter(); List<Literal> plist; MustBeTrue(plist.insertAtEnd(posIter()) == OK); for (posIter++; !posIter.done() && plit.eq(posIter()); posIter++) { MustBeTrue(plist.insertAtEnd(posIter()) == OK); } // get negative literals in equivalence class Literal nlit = negIter(); List<Literal> nlist; MustBeTrue(nlist.insertAtEnd(negIter()) == OK); for (negIter++; !negIter.done() && nlit.eq(negIter()); negIter++) { MustBeTrue(nlist.insertAtEnd(negIter()) == OK); } // we have a class and a counterpart class // that is negated. check each literal. // ListIterator<Literal> plIter(plist); for ( ; !plIter.done(); plIter++) { // check each literal against the other. ListIterator<Literal> nlIter(nlist); for ( ; !nlIter.done(); nlIter++) { if (equal(plIter(), ~nlIter())) { // we have a tautology if (verbose) { cout << endl; cout << "clause is a tautology ..." << endl; cout << "clause: " << c << endl; } return(OK); } } } } } // not a tautology return(NOMATCH); }
void BoolExpr::NNF::rel(Home home, IntConLevel icl) const { switch (t) { case NT_VAR: Gecode::rel(home, u.a.x->x, IRT_EQ, u.a.neg ? 0 : 1); break; case NT_RLIN: u.a.x->rl.post(home, !u.a.neg, icl); break; #ifdef GECODE_HAS_SET_VARS case NT_RSET: u.a.x->rs.post(home, !u.a.neg); break; #endif case NT_MISC: { BoolVar b(home,!u.a.neg,!u.a.neg); u.a.x->m->post(home, b, false, icl); } break; case NT_AND: u.b.l->rel(home, icl); u.b.r->rel(home, icl); break; case NT_OR: { BoolVarArgs bp(p), bn(n); int ip=0, in=0; post(home, NT_OR, bp, bn, ip, in, icl); clause(home, BOT_OR, bp, bn, 1); } break; case NT_EQV: if (u.b.l->t==NT_VAR && u.b.r->t==NT_RLIN) { u.b.r->u.a.x->rl.post(home, u.b.l->u.a.x->x, u.b.l->u.a.neg==u.b.r->u.a.neg, icl); } else if (u.b.r->t==NT_VAR && u.b.l->t==NT_RLIN) { u.b.l->u.a.x->rl.post(home, u.b.r->u.a.x->x, u.b.l->u.a.neg==u.b.r->u.a.neg, icl); } else if (u.b.l->t==NT_RLIN) { u.b.l->u.a.x->rl.post(home, u.b.r->expr(home,icl), !u.b.l->u.a.neg,icl); } else if (u.b.r->t==NT_RLIN) { u.b.r->u.a.x->rl.post(home, u.b.l->expr(home,icl), !u.b.r->u.a.neg,icl); #ifdef GECODE_HAS_SET_VARS } else if (u.b.l->t==NT_VAR && u.b.r->t==NT_RSET) { u.b.r->u.a.x->rs.post(home, u.b.l->u.a.x->x, u.b.l->u.a.neg==u.b.r->u.a.neg); } else if (u.b.r->t==NT_VAR && u.b.l->t==NT_RSET) { u.b.l->u.a.x->rs.post(home, u.b.r->u.a.x->x, u.b.l->u.a.neg==u.b.r->u.a.neg); } else if (u.b.l->t==NT_RSET) { u.b.l->u.a.x->rs.post(home, u.b.r->expr(home,icl), !u.b.l->u.a.neg); } else if (u.b.r->t==NT_RSET) { u.b.r->u.a.x->rs.post(home, u.b.l->expr(home,icl), !u.b.r->u.a.neg); #endif } else { Gecode::rel(home, expr(home, icl), IRT_EQ, 1); } break; default: GECODE_NEVER; } }
BoolVar BoolExpr::NNF::expr(Home home, IntConLevel icl) const { if ((t == NT_VAR) && !u.a.neg) return u.a.x->x; BoolVar b(home,0,1); switch (t) { case NT_VAR: assert(u.a.neg); Gecode::rel(home, u.a.x->x, IRT_NQ, b); break; case NT_RLIN: u.a.x->rl.post(home, b, !u.a.neg, icl); break; #ifdef GECODE_HAS_SET_VARS case NT_RSET: u.a.x->rs.post(home, b, !u.a.neg); break; #endif case NT_MISC: u.a.x->m->post(home, b, !u.a.neg, icl); break; case NT_AND: { BoolVarArgs bp(p), bn(n); int ip=0, in=0; post(home, NT_AND, bp, bn, ip, in, icl); clause(home, BOT_AND, bp, bn, b); } break; case NT_OR: { BoolVarArgs bp(p), bn(n); int ip=0, in=0; post(home, NT_OR, bp, bn, ip, in, icl); clause(home, BOT_OR, bp, bn, b); } break; case NT_EQV: { bool n = false; BoolVar l; if (u.b.l->t == NT_VAR) { l = u.b.l->u.a.x->x; if (u.b.l->u.a.neg) n = !n; } else { l = u.b.l->expr(home,icl); } BoolVar r; if (u.b.r->t == NT_VAR) { r = u.b.r->u.a.x->x; if (u.b.r->u.a.neg) n = !n; } else { r = u.b.r->expr(home,icl); } Gecode::rel(home, l, n ? BOT_XOR : BOT_EQV, r, b, icl); } break; default: GECODE_NEVER; } return b; }