📄 simpsolver.c
字号:
/************************************************************************************[SimpSolver.C]MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas SorenssonPermission is hereby granted, free of charge, to any person obtaining a copy of this software andassociated documentation files (the "Software"), to deal in the Software without restriction,including without limitation the rights to use, copy, modify, merge, publish, distribute,sublicense, and/or sell copies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies orsubstantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUTNOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUTOF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.**************************************************************************************************/#include "Sort.h"#include "SimpSolver.h"#include <iostream>namespace minisat { //================================================================================================= // Constructor/Destructor: SimpSolver::SimpSolver() : grow (0) , asymm_mode (false) , redundancy_check (false) , merges (0) , asymm_lits (0) , remembered_clauses (0) , elimorder (1) , use_simplification (true) , elim_heap (ElimLt(n_occ)) , bwdsub_assigns (0) { vec<Lit> dummy(1,lit_Undef); bwdsub_tmpunit = Clause_new(dummy); remove_satisfied = false; } SimpSolver::~SimpSolver() { free(bwdsub_tmpunit); // NOTE: elimtable.size() might be lower than nVars() at the moment for (int i = 0; i < elimtable.size(); i++) for (int j = 0; j < elimtable[i].eliminated.size(); j++) free(elimtable[i].eliminated[j]); } Var SimpSolver::newVar(bool sign, bool dvar) { Var v = Solver::newVar(sign, dvar); if (use_simplification){ n_occ .push(0); n_occ .push(0); occurs .push(); frozen .push((char)false); touched .push(0); elim_heap.insert(v); elimtable.push(); } return v; } bool SimpSolver::solve(bool do_simp, bool turn_off_simp) { bool result = true; do_simp &= use_simplification; if (do_simp){ result = eliminate(turn_off_simp); litToint(); } return result; } 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); // Alle Kandidaten f"ur subsumption sind in subsumption_queue 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])]++; // Number of occurences von der Variablen c[i] touched[var(c[i])] = 1; // Variable in der added-Klausel assert(elimtable[var(c[i])].order == 0); if (elim_heap.inHeap(var(c[i]))) elim_heap.increase_(var(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); } 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; } // 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; } // 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; } void SimpSolver::gatherTouchedClauses() { //fprintf(stderr, "Gathering clauses for backwards subsumption\n"); int ntouched = 0; for (int i = 0; i < touched.size(); i++) if (touched[i]){ const vec<Clause*>& cs = getOccurs(i); ntouched++; for (int j = 0; j < cs.size(); j++) if (cs[j]->mark() == 0){ subsumption_queue.insert(cs[j]); cs[j]->mark(2); } touched[i] = 0; } for (int i = 0; i < subsumption_queue.size(); i++) subsumption_queue[i]->mark(0); } bool SimpSolver::implied(const vec<Lit>& c) { assert(decisionLevel() == 0); trail_lim.push(trail.size()); for (int i = 0; i < c.size(); i++) if (value(c[i]) == l_True){ cancelUntil(0); return false; }else if (value(c[i]) != l_False){ assert(value(c[i]) == l_Undef); uncheckedEnqueue(~c[i]);// Enqueue a literal. Assumes value of literal is undefined. } bool result = propagate() != NULL; cancelUntil(0); return result; } // Backward subsumption + backward subsumption resolution bool SimpSolver::backwardSubsumptionCheck(bool verbose) { int subsumed = 0; int deleted_literals = 0; assert(decisionLevel() == 0); while (subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()){ // Check top-level assignments by creating a dummy clause and placing it in the queue: if (subsumption_queue.size() == 0 && bwdsub_assigns < trail.size()){ Lit l = trail[bwdsub_assigns++]; (*bwdsub_tmpunit)[0] = l; bwdsub_tmpunit->calcAbstraction(); assert(bwdsub_tmpunit->mark() == 0); subsumption_queue.insert(bwdsub_tmpunit); } Clause& c = *subsumption_queue.peek(); subsumption_queue.pop(); if (c.mark()) continue; assert(c.size() > 1 || value(c[0]) == l_True); // Unit-clauses should have been propagated before this point. // Find best variable to scan: Var best = var(c[0]); for (int i = 1; i < c.size(); i++) if (occurs[var(c[i])].size() < occurs[best].size()) best = var(c[i]); // Search all candidates: vec<Clause*>& _cs = getOccurs(best); Clause** cs = (Clause**)_cs; for (int j = 0; j < _cs.size(); j++) if (c.mark()) break; else if (!cs[j]->mark() && cs[j] != &c){ Lit l = c.subsumes(*cs[j]); if (l == lit_Undef) subsumed++, removeClause(*cs[j]); else if (l != lit_Error){ deleted_literals++; if (!strengthenClause(*cs[j], ~l)) return false; // Did current candidate get deleted from cs? Then check candidate at index j again: if (var(l) == best) j--; } } } return true; } bool SimpSolver::asymm(Var v, Clause& c) { assert(decisionLevel() == 0); if (c.mark() || satisfied(c)) return true; trail_lim.push(trail.size()); Lit l = lit_Undef;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -