Clauses Term::getClauses(Assigment a) { Clauses cs; for (unsigned int i = 0; i < clauses.size(); i++) { Clause c; auto addClause = true; for (auto it : clauses[i]) { auto var = abs(it); if (!a.isSet(var)) { c.insert(it); continue; } if (it > 0 && a.isTrue(var) || it < 0 && a.isFalse(var)) { addClause = false; break; } if (it > 0 && a.isFalse(var) || it < 0 && a.isTrue(var)) continue; c.insert(it); } if (addClause) cs.push_back(c); else { c.clear(); c.insert(0); cs.push_back(c); } } return cs; }
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); }
Clause Term::getClause(Assigment a, int i) { Clause c; auto addClause = true; for (auto it:clauses[i]) { auto var = abs(it); if (!a.isSet(var)) { c.insert(it); continue; } if (it > 0 && a.isTrue(var) || it < 0 && a.isFalse(var)) { addClause = false; break; } else if (it > 0 && a.isFalse(var) || it < 0 && a.isTrue(var)) continue; else c.insert(it); } if (addClause) return c; c.clear(); c.insert(0); return c; }
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; }
// 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; }
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; }
void HyperEngine::add_hyper_bin(const Lit p, const Clause& cl) { assert(value(p.var()) == l_Undef); #ifdef VERBOSE_DEBUG_FULLPROP cout << "Enqueing " << p << " with ancestor clause: " << cl << endl; #endif currAncestors.clear(); size_t i = 0; for (Clause::const_iterator it = cl.begin(), end = cl.end() ; it != end ; ++it, i++ ) { if (*it != p) { assert(value(*it) == l_False); if (varData[it->var()].level != 0) currAncestors.push_back(~*it); } } add_hyper_bin(p); }
/** @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)); }
Node::Node(Node::Serialized& s) { int i; // Someday I'll find out why copy doesn't work here this->unassigned_atoms.clear(); for (i = 0; i < s.unassigned_atoms_count; ++i) this->unassigned_atoms.insert(s.unassigned_atoms[i]); this->assignments.clear(); for (i = 0; i < s.assignments_count; ++i) { int atom = abs(s.assignments[i]); this->assignments[atom] = (s.assignments[i] > 0); } // The following takes care of both clauses and literals list this->clauses.clear(); this->literals.clear(); i = 0; while (i < s.clauses_count) { Clause c; while (s.clauses[i] != 0) { Literal l(s.clauses[i]); c.add_literal(l); this->literals[l]++; ++i; } this->add_clause(c); ++i; } }
// 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; }
// 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; }
// get clause data int Atomic::getClauses(ombt::Set_List<Clause> &clist, Clause &c, int storeClause, int negated, int concluded) const { Atom atom; switch (type) { case Constant: atom = Atom(value); if (negated) { if (atom == Atom("true")) atom = Atom("false"); else atom = Atom("true"); } break; case Variable: if (negated) atom = ~Atom(name); else atom = Atom(name); break; default: MustBeTrue(0); return(NOTOK); } c.setPartOfConclusion(concluded); c.insert(atom); return(OK); }
Clause* QueryInterface::computeClauseFromCandidates() { Clause* clause = new Clause(); unsigned int j = 0; for( unsigned int i = 0; i < candidates.size(); i++ ) { Var v = candidates[ j ] = candidates[ i ]; assert( !solver.isUndefined( v ) ); if( !solver.isTrue( v ) ) continue; if( solver.getDecisionLevel( v ) == 0 ) addAnswer( v ); else { clause->addLiteral( Literal( v, NEGATIVE ) ); j++; } } candidates.shrink( j ); clause->setCanBeDeleted( false ); printCandidates(); return clause; }
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)); }
void ReduceDB::mark_top_N_clauses(const uint64_t keep_num) { size_t marked = 0; for(size_t i = 0 ; i < solver->longRedCls[1].size() && marked < keep_num ; i++ ) { const ClOffset offset = solver->longRedCls[1][i]; Clause* cl = solver->cl_alloc.ptr(offset); if ( cl->stats.locked || cl->used_in_xor() || cl->stats.ttl > 0 || solver->clause_locked(*cl, offset) || cl->stats.glue <= solver->conf.glue_must_keep_clause_if_below_or_eq ) { //no need to mark, skip continue; } if (!cl->stats.marked_clause) { marked++; cl->stats.marked_clause = true; } } }
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(); }
Clause* DavisPutnamSolveur::resolution(const Clause* c1, Clause* c2, const int id) const { Clause* sortie = new Clause(*c1); sortie->fusionner(c2); sortie->supprimer(formule.getLiteral(id)); sortie->supprimer(formule.getLiteral(-id)); return sortie; }
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(); }
/** @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 BacktrackEnumerator::undoLevel(Solver& s) { while (!nogoods_.empty() && nogoods_.back().second >= s.decisionLevel()) { Clause* c = (Clause*)nogoods_.back().first; nogoods_.pop_back(); *c->end() = posLit(0); c->removeWatches(s); c->destroy(); } }
// dump any new clause void dumpnewclause(const Clause &cl1, const Clause &cl2, const Clause &newcl) { cout << "((p1,l1), (p2,l2)) = (("; cout << cl1.getNumber() << "," << cl1.getTotalMembers() << "),("; cout << cl2.getNumber() << "," << cl2.getTotalMembers() << ")) = "; cout << newcl << endl; return; }
Clause::Clause(const Clause &c): m_literals(c.getNbLiterals()) { int nbLiterals = c.getNbLiterals(); for (int i = 0; i < nbLiterals; ++i){ m_literals[i] = c(i); } sort(); }
PropResult PropEngine::prop_normal_helper( Clause& c , ClOffset offset , watch_subarray::iterator &j , const Lit p ) { #ifdef STATS_NEEDED c.stats.clause_looked_at++; c.stats.visited_literals++; #endif // Make sure the false literal is data[1]: if (c[0] == ~p) { std::swap(c[0], c[1]); } assert(c[1] == ~p); // If 0th watch is true, then clause is already satisfied. if (value(c[0]) == l_True) { *j = Watched(offset, c[0]); j++; return PROP_NOTHING; } // Look for new watch: #ifdef STATS_NEEDED uint32_t numLitVisited = 0; #endif for (Lit *k = c.begin() + 2, *end2 = c.end() ; k != end2 ; k++ #ifdef STATS_NEEDED , numLitVisited++ #endif ) { //Literal is either unset or satisfied, attach to other watchlist if (value(*k) != l_False) { c[1] = *k; #ifdef STATS_NEEDED //propStats.bogoProps += numLitVisited/10; c.stats.visited_literals+= numLitVisited; #endif *k = ~p; watches[c[1].toInt()].push(Watched(offset, c[0])); return PROP_NOTHING; } } #ifdef STATS_NEEDED //propStats.bogoProps += numLitVisited/10; c.stats.visited_literals+= numLitVisited; #endif return PROP_TODO; }
// Construct the set of clauses for TRUE truth value of a fact at a level bool StripsEncoding::supporting_constraints(int ft, int level, ClauseSet& clauses) const { //#define DEBUG_SUPPORTING_CONSTRAINTS #ifdef DEBUG_SUPPORTING_CONSTRAINTS int t=2; TAB(t); cout<<"In supporting constraints: ft = "<<ft<<", level = "<<level<<endl; #endif if (clauses.size()) clauses.clear(); if (level < 0 || level > this->actions.size()) return false; if (!is_in_state(ft, this->states[level])) // There's no way to satisfy this fact return false; int confirmed_level = get_confirmed_level(ft, level); #ifdef DEBUG_SUPPORTING_CONSTRAINTS TAB(t+1); cout<<"Confirmed level: "<<confirmed_level<<endl; #endif // If "ft" is false at the confirmed level, we first need "establishment constraints" if (!is_in_state(ft, this->states[confirmed_level])) { Clause c; int k; for (k = confirmed_level; k < level; k++) if (is_poss_add(ft, this->actions[k])) { int bvar = get_bool_var(ft, this->actions[k], POSS_ADD); c.add_literal(bvar); } clauses.add_clause(c); } // Protection constraints for (int k = confirmed_level; k < level; k++) if (is_poss_del(ft, this->actions[k])) { Clause c; int bvar = get_bool_var(ft, this->actions[k], POSS_DEL); c.add_literal(-bvar); for (int j=k+1;j<level;j++) { if (is_poss_add(ft, this->actions[j])) { bvar = get_bool_var(ft, this->actions[j], POSS_ADD); c.add_literal(bvar); } } clauses.add_clause(c); } return true; }
Clause * Clause::copy ( void ) { Clause * c = new Clause ( guard->copy() ); for ( i = commands->begin(); i != commands->end(); i++ ) c->addCommand ( (*i)->copy() ); return c; }
Clause * Clause::subst ( Expr * e, char * x ) { Clause * c = new Clause ( guard->subst(e,x) ); for ( i = commands->begin(); i != commands->end(); i++ ) c->addCommand ( (*i)->subst(e,x) ); return c; }
void ClauseAllocator::updateAllOffsetsAndPointers( Solver* solver , const vector<ClOffset>& offsets ) { //Must be at toplevel, otherwise propBy reset will not work //and also, detachReattacher will fail assert(solver->decisionLevel() == 0); //We are at decision level 0, so we can reset all PropBy-s for (auto& vdata: solver->varData) { vdata.reason = PropBy(); } //Detach long clauses CompleteDetachReatacher detachReattach(solver); detachReattach.detach_nonbins_nontris(); //Make sure all non-freed clauses were accessible from solver const size_t origNumClauses = solver->longIrredCls.size() + solver->longRedCls.size(); if (origNumClauses != offsets.size()) { std::cerr << "ERROR: Not all non-freed clauses are accessible from Solver" << endl << " This usually means that a clause was not freed, i.e. a mem leak" << endl << " no. clauses accessible from solver: " << origNumClauses << endl << " no. clauses non-freed: " << offsets.size() << endl; assert(origNumClauses == offsets.size()); std::exit(-1); } //Clear clauses solver->longIrredCls.clear(); solver->longRedCls.clear(); //Add back to the solver the correct red & irred clauses for(auto offset: offsets) { Clause* cl = ptr(offset); assert(!cl->freed()); //Put it in the right bucket if (cl->red()) { solver->longRedCls.push_back(offset); } else { solver->longIrredCls.push_back(offset); } } //Finally, reattach long clauses detachReattach.reattachLongs(); }
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); }
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 Master::disposeObsolete() { CALL("disposeObsolete()"); Clause* disposedClause; while (_queueForDisposal.dequeue(disposedClause)) { ASSERT(disposedClause->mainSet() == Clause::MainSetTrash); disposedClause->setMainSet(Clause::MainSetFree); disposeClause(disposedClause); }; }; // void Master::disposeObsolete()