// Returns FALSE if clause is always satisfied. bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, int& size) { merges++; bool ps_smallest = _ps.size() < _qs.size(); const Clause& ps = ps_smallest ? _qs : _ps; const Clause& qs = ps_smallest ? _ps : _qs; const Lit* __ps = static_cast<const Lit*>(ps); const Lit* __qs = static_cast<const Lit*>(qs); size = ps.size()-1; for (int i = 0; i < qs.size(); i++) { if (var(__qs[i]) != v) { for (int j = 0; j < ps.size(); j++) { if (var(__ps[j]) == var(__qs[i])) { if (__ps[j] == ~__qs[i]) return false; else goto next; } } size++; } next:; } return true; }
/** @brief Cleans clauses from failed literals/removes satisfied clauses from cs May change solver->ok to FALSE (!) */ void CompleteDetachReatacher::cleanAndAttachClauses( vector<ClOffset>& cs , bool removeStatsFirst ) { assert(!solver->drup->something_delayed()); vector<ClOffset>::iterator i = cs.begin(); vector<ClOffset>::iterator j = i; for (vector<ClOffset>::iterator end = cs.end(); i != end; i++) { Clause* cl = solver->clAllocator.getPointer(*i); //Handle stat removal if need be if (removeStatsFirst) { if (cl->red()) { solver->litStats.redLits -= cl->size(); } else { solver->litStats.irredLits -= cl->size(); } } if (cleanClause(cl)) { solver->attachClause(*cl); *j++ = *i; } else { solver->clAllocator.clauseFree(*i); } } cs.resize(cs.size() - (i-j)); }
void SAT::removeClause(Clause& c) { assert(c.size() > 1); watches[toInt(~c[0])].remove(&c); watches[toInt(~c[1])].remove(&c); if (c.learnt) learnts_literals -= c.size(); else clauses_literals -= c.size(); if (c.learnt) for (int i = 0; i < c.size(); i++) decVarUse(var(c[i])); if (c.learnt) { // learntClauseScore[c.clauseID()] = c.rawActivity(); /* if (so.debug) { */ if (so.learnt_stats) { int id = c.clauseID(); learntStatsStream << learntClauseString[id]; learntStatsStream << ","; learntStatsStream << c.rawActivity(); learntStatsStream << "\n"; /* std::cerr << "clausescore," << << "," << c.rawActivity() << "\n"; */ } /* } */ } free(&c); }
void PropEngine::attachClause( const Clause& c , const bool checkAttach ) { assert(c.size() > 3); if (checkAttach) { assert(value(c[0]) == l_Undef); assert(value(c[1]) == l_Undef || value(c[1]) == l_False); } if (c.red() && red_long_cls_is_reducedb(c)) { num_red_cls_reducedb++; } #ifdef DEBUG_ATTACH for (uint32_t i = 0; i < c.size(); i++) { assert(varData[c[i].var()].removed == Removed::none); } #endif //DEBUG_ATTACH const ClOffset offset = cl_alloc.get_offset(&c); const Lit blocked_lit = find_good_blocked_lit(c); watches[c[0].toInt()].push(Watched(offset, blocked_lit)); watches[c[1].toInt()].push(Watched(offset, blocked_lit)); }
// Returns FALSE if clause is always satisfied. bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v) { merges++; bool ps_smallest = _ps.size() < _qs.size(); const Clause& ps = ps_smallest ? _qs : _ps; const Clause& qs = ps_smallest ? _ps : _qs; const Lit* __ps = (const Lit*)ps; const Lit* __qs = (const Lit*)qs; for (int i = 0; i < qs.size(); i++){ if (var(__qs[i]) != v){ for (int j = 0; j < ps.size(); j++) if (var(__ps[j]) == var(__qs[i])) { if (__ps[j] == ~__qs[i]) return false; else goto next; } } next:; } return true; }
// Returns FALSE if clause is always satisfied ('out_clause' should not be used). bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause) { merges++; out_clause.clear(); bool ps_smallest = _ps.size() < _qs.size(); const Clause& ps = ps_smallest ? _qs : _ps; const Clause& qs = ps_smallest ? _ps : _qs; for (int i = 0; i < qs.size(); i++) { if (var(qs[i]) != v) { for (int j = 0; j < ps.size(); j++) { if (var(ps[j]) == var(qs[i])) { if (ps[j] == ~qs[i]) return false; else goto next; } } out_clause.push(qs[i]); } next:; } for (int i = 0; i < ps.size(); i++) if (var(ps[i]) != v) out_clause.push(ps[i]); return true; }
/** @brief Returns if the two clauses are equal NOTE: assumes that the clauses are of equal lenght AND contain the same variables (but the invertedness of the literals might differ) */ bool XorFinder::clauseEqual(const Clause& c1, const Clause& c2) const { assert(c1.size() == c2.size()); for (uint32_t i = 0, size = c1.size(); i < size; i++) if (c1[i].sign() != c2[i].sign()) return false; return true; }
void Solver::detachClause(Clause& c) { assert(c.size() > 1); assert(find(watches[toInt(~c[0])], &c)); assert(find(watches[toInt(~c[1])], &c)); remove(watches[toInt(~c[0])], &c); remove(watches[toInt(~c[1])], &c); if (c.learnt()) learnts_literals -= c.size(); else clauses_literals -= c.size(); }
void MiniSATP::attachClause(Clause& c) { assert(c.size() > 1); watches[toInt(~c[0])].push(&c); watches[toInt(~c[1])].push(&c); if (c.learnt()) learnts_literals += c.size(); else clauses_literals += c.size(); }
void SAT::removeClause(Clause& c) { assert(c.size() > 1); watches[toInt(~c[0])].remove(&c); watches[toInt(~c[1])].remove(&c); if (c.learnt) learnts_literals -= c.size(); else clauses_literals -= c.size(); if (c.learnt) for (int i = 0; i < c.size(); i++) decVarUse(var(c[i])); free(&c); }
void Solver::detachClause(Clause& c) { assert(c.size() > 1); // assert(find(watches[toInt(~c[0])], &c)); //assert(find(watches[toInt(~c[1])], &c)); if(c.size()==2) { removeBin(watchesBin[toInt(~c[0])],&c); removeBin(watchesBin[toInt(~c[1])],&c); } else { removeW(watches[toInt(~c[0])], &c); removeW(watches[toInt(~c[1])], &c); } if (c.learnt()) learnts_literals -= c.size(); else clauses_literals -= c.size(); }
void SAT::addClause(Clause& c, bool one_watch) { assert(c.size() > 0); if (c.size() == 1) { assert(decisionLevel() == 0); if (DEBUG) fprintf(stderr, "warning: adding length 1 clause!\n"); if (value(c[0]) == l_False) TL_FAIL(); if (value(c[0]) == l_Undef) enqueue(c[0]); free(&c); return; } if (!c.learnt) { if (c.size() == 2) bin_clauses++; else if (c.size() == 3) tern_clauses++; else long_clauses++; } // Mark lazy lits which are used if (c.learnt) for (int i = 0; i < c.size(); i++) incVarUse(var(c[i])); if (c.size() == 2) { if (!one_watch) watches[toInt(~c[0])].push(c[1]); watches[toInt(~c[1])].push(c[0]); if (!c.learnt) free(&c); return; } if (!one_watch) watches[toInt(~c[0])].push(&c); watches[toInt(~c[1])].push(&c); if (c.learnt) learnts_literals += c.size(); else clauses_literals += c.size(); if (c.received) receiveds.push(&c); else if (c.learnt) learnts.push(&c); else clauses.push(&c); }
/** @brief Helper function for replace_set() */ bool VarReplacer::handleUpdatedClause(Clause& c, const Lit origLit1, const Lit origLit2, const Lit origLit3) { bool satisfied = false; std::sort(c.getData(), c.getData() + c.size()); Lit p; uint32_t i, j; const uint32_t origSize = c.size(); for (i = j = 0, p = lit_Undef; i != origSize; i++) { if (solver.value(c[i]) == l_True || c[i] == ~p) { satisfied = true; break; } else if (solver.value(c[i]) != l_False && c[i] != p) c[j++] = p = c[i]; } c.shrink(i - j); c.setChanged(); solver.detachModifiedClause(origLit1, origLit2, origLit3, origSize, &c); #ifdef VERBOSE_DEBUG cout << "clause after replacing: "; c.plainPrint(); #endif if (satisfied) return true; switch(c.size()) { case 0: solver.ok = false; return true; case 1 : solver.uncheckedEnqueue(c[0]); solver.ok = (solver.propagate<false>().isNULL()); return true; case 2: solver.attachBinClause(c[0], c[1], c.learnt()); solver.numNewBin++; solver.dataSync->signalNewBinClause(c); return true; default: solver.attachClause(c); return false; } assert(false); return false; }
void ReduceDB::remove_cl_from_array_and_count_stats( CleaningStats& tmpStats , uint64_t sumConfl ) { size_t i, j; for (i = j = 0 ; i < solver->longRedCls[1].size() ; i++ ) { ClOffset offset = solver->longRedCls[1][i]; Clause* cl = solver->cl_alloc.ptr(offset); assert(cl->size() > 3); if (cl->stats.locked) { cl_locked++; } else if (cl->stats.marked_clause) { cl_marked++; } else if (cl->stats.ttl != 0) { cl_ttl++; } else if (solver->clause_locked(*cl, offset)) { cl_locked_solver++; } if (cl->stats.glue <= solver->conf.glue_must_keep_clause_if_below_or_eq) { solver->longRedCls[0].push_back(offset); continue; } if (!cl_needs_removal(cl, offset)) { cl->stats.ttl = 0; solver->longRedCls[1][j++] = offset; tmpStats.remain.incorporate(cl, sumConfl); cl->stats.marked_clause = 0; continue; } //Stats Update cl->setRemoved(); solver->watches.smudge((*cl)[0]); solver->watches.smudge((*cl)[1]); tmpStats.removed.incorporate(cl, sumConfl); solver->litStats.redLits -= cl->size(); *solver->drat << del << *cl << fin; delayed_clause_free.push_back(offset); } solver->longRedCls[1].resize(j); }
PropResult PropEngine::handle_normal_prop_fail( Clause& c , ClOffset offset , PropBy& confl ) { confl = PropBy(offset); #ifdef VERBOSE_DEBUG_FULLPROP cout << "Conflict from "; for(size_t i = 0; i < c.size(); i++) { cout << c[i] << " , "; } cout << endl; #endif //VERBOSE_DEBUG_FULLPROP //Update stats #ifdef STATS_NEEDED c.stats.conflicts_made++; c.stats.sum_of_branch_depth_conflict += decisionLevel() + 1; #endif if (c.red()) lastConflictCausedBy = ConflCausedBy::longred; else lastConflictCausedBy = ConflCausedBy::longirred; qhead = trail.size(); return PROP_FAIL; }
bool ClauseCleaner::satisfied(const Clause& c) const { for (uint32_t i = 0; i != c.size(); i++) if (solver.value(c[i]) == l_True) return true; return false; }
void Manager::View::cleanClause(Clause & clause) { exprView.sort(clause.begin(), clause.end()); for (Clause::iterator it = clause.begin(); it != clause.end(); ) { if (*it == exprView.btrue()) // [true lit] throw Trivial(true); else if (*it == exprView.bfalse()) // [false lit] clause.erase(it); else if (it+1 != clause.end()) { if (*it == *(it+1)) { // [repetition of lit] clause.erase(it); } else if (*it == exprView.apply(Expr::Not, *(it+1))) // [var with both phases] // Relies on how Expr handles negation, so possibly a hack. // However, I meant for this property to be usable, so it // will be maintained. throw Trivial(true); else it++; } else it++; } if (clause.size() == 0) // empty clause throw Trivial(false); }
bool SimpSMTSolver::asymm(Var v, Clause& c) { assert(decisionLevel() == 0); if (c.mark() || satisfied(c)) return true; trail_lim.push(trail.size()); Lit l = lit_Undef; for (int i = 0; i < c.size(); i++) if (var(c[i]) != v && value(c[i]) != l_False) { uncheckedEnqueue(~c[i]); } else l = c[i]; if (propagate() != NULL){ cancelUntil(0); asymm_lits++; if (!strengthenClause(c, l)) return false; }else cancelUntil(0); return true; }
/** @brief Returns whether the number of inverted literals in the clause is pair or impair */ bool XorFinder::impairSigns(const Clause& c) const { uint32_t num = 0; for (const Lit *it = &c[0], *end = it + c.size(); it != end; it++) num += it->sign(); return num % 2; }
void SimpSolver::toDimacs(FILE* f, Clause& c) { if (satisfied(c)) return; for (int i = 0; i < c.size(); i++) if (value(c[i]) != l_False) fprintf(f, "%s%d ", sign(c[i]) ? "-" : "", var(c[i])+1); fprintf(f, "0\n"); }
bool SimpSolver::strengthenClause(Clause& c, Lit l) { assert(decisionLevel() == 0); assert(c.mark() == 0); assert(!c.learnt()); assert(find(watches[toInt(~c[0])], &c)); assert(find(watches[toInt(~c[1])], &c)); // FIX: this is too inefficient but would be nice to have (properly implemented) // if (!find(subsumption_queue, &c)) subsumption_queue.insert(&c); // If l is watched, delete it from watcher list and watch a new literal if (c[0] == l || c[1] == l){ Lit other = c[0] == l ? c[1] : c[0]; if (c.size() == 2){ removeClause(c); c.strengthen(l); }else{ c.strengthen(l); remove(watches[toInt(~l)], &c); // Add a watch for the correct literal watches[toInt(~(c[1] == other ? c[0] : c[1]))].push(&c); // !! this version assumes that remove does not change the order !! //watches[toInt(~c[1])].push(&c); clauses_literals -= 1; } } else{ c.strengthen(l); clauses_literals -= 1; } // if subsumption-indexing is active perform the necessary updates if (use_simplification){ remove(occurs[var(l)], &c); n_occ[toInt(l)]--; updateElimHeap(var(l)); } return c.size() == 1 ? enqueue(c[0]) && propagate() == NULL : true; }
bool Aggregate::checkDecisionLevelsOrder( const Solver& solver, const Clause& clause ) const { if( clause.size() <= 1 ) return true; unsigned int max1 = solver.isUndefined( clause[ 0 ] ) ? MAXUNSIGNEDINT : solver.getDecisionLevel( clause[ 0 ] ); unsigned int max2 = solver.getDecisionLevel( clause[ 1 ] ); for( unsigned int i = 2; i < clause.size(); i++ ) { unsigned int dl = solver.getDecisionLevel( clause[ i ] ); if( dl > max1 || dl > max2 ) return false; } return max1 >= max2; }
bool SAT::simplify(Clause& c) { if (value(c[0]) == l_True) return true; if (value(c[1]) == l_True) return true; int i, j; for (i = j = 2; i < c.size(); i++) { if (value(c[i]) == l_True) return true; if (value(c[i]) == l_Undef) c[j++] = c[i]; } c.resize(j); return false; }
void Solver::toDimacs(std::ostream &out, Clause& c, vec<Var>& map, Var& max) { if (satisfied(c)) return; for (int i = 0; i < c.size(); i++){ if (value(c[i]) != l_False) { if (sign(c[i])) { out << "-"; } out << mapVar(var(c[i]), map, max)+1; } } out << "0\n"; }
void Solver::attachClause(Clause& c) { assert(c.size() > 1); if(c.size()==2) { watchesBin[toInt(~c[0])].push(); watchesBin[toInt(~c[1])].push(); watchesBin[toInt(~c[0])].last().clause = &c; watchesBin[toInt(~c[0])].last().implied = c[1]; watchesBin[toInt(~c[1])].last().clause = &c; watchesBin[toInt(~c[1])].last().implied = c[0]; } else { watches[toInt(~c[0])].push(); watches[toInt(~c[1])].push(); watches[toInt(~c[0])].last().wcl = &c; watches[toInt(~c[0])].last().blocked = c[c.size()/2]; watches[toInt(~c[1])].last().wcl = &c; watches[toInt(~c[1])].last().blocked = c[c.size()/2]; } if (c.learnt()) learnts_literals += c.size(); else clauses_literals += c.size(); }
bool SAT::convertToSClause(Clause& c) { assert(c.size() <= TEMP_SC_LEN/2); temp_sc->size = c.size(); temp_sc->extra = 0; temp_sc->source = so.thread_no; int j = 0; // TODO: DO I need this? (=> do I want to send/receive clauses?) /* * Different kind of literals: * - Boolean literal (purely boolean) * - Lazy Literal for integers * - Eager Literal for Integers * */ //fprintf(stderr, "ConvertToSC called! \n"); //fflush(stderr); for (int i = 0; i < c.size(); i++) { int type = c_info[var(c[i])].cons_type; if(type == 2) printf("hmm, prop-lit? \n"); assert(type != 2); int vid = c_info[var(c[i])].cons_id; // TODO: 1. Feld: Name der (Int-LL)-Variablen. // Feld 2: Vorzeichen (1 Bit), Art (1 Bit), Wert (30 Bit)? // ChannelInfo: - Val_type <-> Gleichung/Ungleichung // - Val: if (type == 1 && vid != -1 && engine.vars[vid]->getType() == INT_VAR_LL) { int var_field = (0x8000000 + (vid<<2) + (3*c_info[var(c[i])].val_type))^sign(c[i]); temp_sc->data[j++] = var_field; temp_sc->data[j++] = c_info[var(c[i])].val; temp_sc->extra++; } else { // Only a boolean literal. Okay as // either this is a boolean variable, // or it was encoded the same way for every process //) temp_sc->data[j++] = toInt(c[i]); } } return true; }
void SimpSolver::removeClause(Clause& c) { assert(!c.learnt()); if (use_simplification) for (int i = 0; i < c.size(); i++){ n_occ[toInt(c[i])]--; updateElimHeap(var(c[i])); } detachClause(c); c.mark(1); }
void GateFinder::set_seen2_and_abstraction( const Clause& cl , cl_abst_type& abstraction ) { *simplifier->limit_to_decrease -= cl.size(); for (const Lit lit: cl) { if (!seen2[lit.toInt()]) { seen2[lit.toInt()] = true; seen2Set.push_back(lit.toInt()); } abstraction |= abst_var(lit.var()); } }
/** @brief Helper function for replace_set() */ const bool VarReplacer::handleUpdatedClause(Clause& c, const Lit origLit1, const Lit origLit2, const Lit origLit3) { bool satisfied = false; std::sort(c.getData(), c.getData() + c.size()); Lit p; uint32_t i, j; const uint32_t origSize = c.size(); for (i = j = 0, p = lit_Undef; i != origSize; i++) { if (solver.value(c[i]) == l_True || c[i] == ~p) { satisfied = true; break; } else if (solver.value(c[i]) != l_False && c[i] != p) c[j++] = p = c[i]; } c.shrink(i - j); c.setStrenghtened(); solver.detachModifiedClause(origLit1, origLit2, origLit3, origSize, &c); if (satisfied) return true; switch(c.size()) { case 0: solver.ok = false; return true; case 1 : solver.uncheckedEnqueue(c[0]); solver.ok = (solver.propagate().isNULL()); return true; default: solver.attachClause(c); return false; } assert(false); return false; }
// Modified Lines // void MiniSATP::removeClause(Clause& c) // { void MiniSATP::removeClause(Clause& c) { // Remove clause from reasons // for ( int i = 0 ; i < c.size( ) ; i ++ ) { const Var v = var(c[i]); if ( reason[ v ] == &c ) reason[ v ] = NULL; } detachClause(c); removed.push( &c ); }