void SimpSolver::remember(Var v) { assert(decisionLevel() == 0); assert(isEliminated(v)); vec<Lit> clause; // Re-activate variable: elimtable[v].order = 0; setDecisionVar(v, true); // Not good if the variable wasn't a decision variable before. Not sure how to fix this right now. if (use_simplification) updateElimHeap(v); // Reintroduce all old clauses which may implicitly remember other clauses: for (int i = 0; i < elimtable[v].eliminated.size(); i++){ Clause& c = *elimtable[v].eliminated[i]; clause.clear(); for (int j = 0; j < c.size(); j++) clause.push(c[j]); remembered_clauses++; check(addClause(clause)); free(&c); } elimtable[v].eliminated.clear(); }
bool SimpSolver::addClause(vec<Lit>& ps) { for (int i = 0; i < ps.size(); i++) if (isEliminated(var(ps[i]))) remember(var(ps[i])); int nclauses = clauses.size(); if (redundancy_check && implied(ps)) return true; if (!Solver::addClause(ps)) return false; if (use_simplification && clauses.size() == nclauses + 1){ Clause& c = *clauses.last(); subsumption_queue.insert(&c); for (int i = 0; i < c.size(); i++){ assert(occurs.size() > var(c[i])); assert(!find(occurs[var(c[i])], &c)); occurs[var(c[i])].push(&c); n_occ[toInt(c[i])]++; touched[var(c[i])] = 1; assert(elimtable[var(c[i])].order == 0); if (elim_heap.inHeap(var(c[i]))) elim_heap.increase_(var(c[i])); } } return true; }
lbool SimpSolver::solve(const vec<Lit>& assumps, bool do_simp, bool turn_off_simp) { vec<Var> extra_frozen; lbool result = l_True; do_simp &= use_simplification; do_simp &= (decisionLevel() == 0); if (do_simp){ // Assumptions must be temporarily frozen to run variable elimination: for (int i = 0; i < assumps.size(); i++){ Var v = var(assumps[i]); // If an assumption has been eliminated, remember it. if (isEliminated(v)) remember(v); if (!frozen[v]){ // Freeze and store. setFrozen(v, true); extra_frozen.push(v); } } if(eliminate(turn_off_simp)) result = l_True; else result = l_False; } if (result == l_True) result = Solver::solve(assumps); if (result == l_True) { extendModel(); #ifndef NDEBUG verifyModel(); #endif } if (do_simp) // Unfreeze the assumptions that were frozen: for (int i = 0; i < extra_frozen.size(); i++) setFrozen(extra_frozen[i], false); return result; }
bool SimpSMTSolver::addClause( vec<Lit> & ps #ifdef PRODUCE_PROOF , const ipartitions_t & in #endif ) { //================================================================================================= // Added code if ( !use_simplification ) #ifdef PRODUCE_PROOF return CoreSMTSolver::addClause( ps, in ); #else return CoreSMTSolver::addClause( ps ); #endif // Added code //================================================================================================= for (int i = 0; i < ps.size(); i++) if (isEliminated(var(ps[i]))) remember(var(ps[i])); int nclauses = clauses.size(); if (redundancy_check && implied(ps)) return true; //================================================================================================= // Added code // // Hack to consider clauses of size 1 that // wouldn't otherwise be considered by // MiniSAT // if ( config.sat_preprocess_theory != 0 && ps.size( ) == 1 // Consider unit clauses && var(ps[0]) >= 2 ) // Don't consider true/false { Var v = var( ps[0] ); cerr << "XXX skipped handling of unary theory literal?" << endl; /* Enode * e = theory_handler->varToEnode( v ); if ( e->isTAtom( ) ) { Clause * uc = Clause_new(ps, false); unary_to_remove.push_back( uc ); Clause &c = *(unary_to_remove.back( )); Enode * x, * y; getDLVars( e, sign(ps[0]), &x, &y ); assert( x->isVar( ) ); assert( y->isVar( ) ); t_pos[ x->getId( ) ].push_back( &c ); t_neg[ y->getId( ) ].push_back( &c ); t_var[ x ].insert( y->getId( ) ); t_var[ y ].insert( x->getId( ) ); } */ } // Added code //================================================================================================= if (!CoreSMTSolver::addClause(ps)) return false; if (use_simplification && clauses.size() == nclauses + 1) { Clause& c = *clauses.last(); subsumption_queue.insert(&c); for (int i = 0; i < c.size(); i++) { assert(occurs.size() > var(c[i])); assert(!find(occurs[var(c[i])], &c)); occurs[var(c[i])].push(&c); n_occ[toInt(c[i])]++; touched[var(c[i])] = 1; assert(elimtable[var(c[i])].order == 0); if (elim_heap.inHeap(var(c[i]))) elim_heap.increase_(var(c[i])); } } return true; }
lbool SimpSMTSolver::solve( const vec< Lit > & assumps , const unsigned conflicts , bool do_simp , bool turn_off_simp) { vec<Var> extra_frozen; bool result = true; if ( config.sat_preprocess_theory == 0 ) goto skip_theory_preproc; opensmt_error( "preprocess theory has been temporairly disabled in this version" ); skip_theory_preproc: // Added Code //================================================================================================= do_simp &= use_simplification; if (do_simp) { // Assumptions must be temporarily frozen to run variable elimination: for (int i = 0; i < assumps.size(); i++) { Var v = var(assumps[i]); // If an assumption has been eliminated, remember it. if (isEliminated(v)) remember(v); if (!frozen[v]) { // Freeze and store. setFrozen(v, true); extra_frozen.push(v); } } result = eliminate(turn_off_simp); } #ifdef STATISTICS CoreSMTSolver::preproc_time = cpuTime( ); #endif lbool lresult = l_Undef; if (result) lresult = CoreSMTSolver::solve(assumps, conflicts); else lresult = l_False; if (lresult == l_True) { extendModel(); // Previous line // #ifndef NDEBUG #ifndef SMTCOMP verifyModel(); #endif } if (do_simp) // Unfreeze the assumptions that were frozen: for (int i = 0; i < extra_frozen.size(); i++) setFrozen(extra_frozen[i], false); return lresult; }