boost::unordered_set<Model> MCSat::sampleSat(const Model& initialModel, const Domain& d, boost::mt19937& rng) { boost::unordered_set<Model> models; models.insert(initialModel); // always include the initial model // transform domain into a SAT problem Domain dSat; for (Domain::fact_const_iterator it = d.facts_begin(); it != d.facts_end(); it++) { dSat.addFact(*it); } for (Domain::formula_const_iterator it = d.formulas_begin(); it != d.formulas_end(); it++) { ELSentence s = *it; s.setHasInfWeight(true); dSat.addFormula(s); } dSat.addAtoms(d.atoms_begin(), d.atoms_end()); // perform UP (if possible) Domain reduced; if (useUnitPropagation_) { try { reduced = MCSat::applyUP(dSat); } catch (contradiction& c) { return models; // can't continue, just return our models which has only one item. } } else { reduced = dSat; } // rewrite infinite weighted formulas so they have singular weight reduced = reduced.replaceInfForms(); // do some random restarts and hope for different models MWSSolver walksatSolver(walksatIterations_, walksatRandomMoveProb_, &reduced); for (unsigned int i = 1; i <= walksatNumRandomRestarts_; i++) { Model iterInitModel = reduced.randomModel(rng); // TODO: better way to make random models if (reduced.formulas_size() == 0) { // just add the random model and continue models.insert(reduced.randomModel(rng)); continue; } //std::cout << "--\nFormulas for maxwalksat: "; //std::copy(reduced.formulas_begin(), reduced.formulas_end(), std::ostream_iterator<ELSentence>(std::cout, ", ")); //std::cout << std::endl; Model iterModel = walksatSolver.run(rng, iterInitModel); if (reduced.isFullySatisfied(iterModel)) models.insert(iterModel); } return models; }
Domain MCSat::applyUP(const Domain& d) { Domain reduced; try { reduced = performUnitPropagation(d); } catch (contradiction& c) { // rewrite error message throw contradiction("Contradiction found in MCSat::run() when running unit prop()"); } // default model is guaranteed to satisfy the facts Model m = reduced.defaultModel(); // check to make sure hard clauses are satisfied std::vector<ELSentence> hardClauses; std::remove_copy_if(reduced.formulas_begin(), reduced.formulas_end(), std::back_inserter(hardClauses), std::not1(IsHardClausePred())); for (std::vector<ELSentence>::const_iterator it = hardClauses.begin(); it != hardClauses.end(); it++) { if (!it->fullySatisfied(m, reduced)) { throw contradiction("Contradiction found in MCSat::run() when verifying hard clauses are satisfied"); } } return reduced; }