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; }
void MCSat::run(boost::mt19937& rng) { // TODO: setup using random initial models if (d_ == 0) { throw std::logic_error("MCSat::run() - Domain not set"); } if (sampleStrategy_ == 0) { throw std::logic_error("MCSat::run() - SampleStrategy not set"); } samples_.clear(); samples_.reserve(numSamples_); //std::cout << "initial domain: "; //d_->printDebugDescription(std::cout); // first, run unit propagation on our domain to get a new reduced one. Domain reduced; if (useUnitPropagation_) { reduced = MCSat::applyUP(*d_); } else { reduced = *d_; } //std::cout << "reduced domain: "; //reduced.printDebugDescription(std::cout); Model prevModel = (useRandomInitialModels_ ? reduced.randomModel(rng) : reduced.defaultModel()); // do a starting run on the whole problem as our initial sample //boost::unordered_set<Model> initModels = sampleSat(prevModel, reduced); //prevModel = *initModels.begin(); Domain prevDomain = reduced; if (burnInIterations_ == 0) samples_.push_back(prevModel); unsigned int totalIterations = numSamples_+burnInIterations_; for (unsigned int iteration = 1; iteration < totalIterations; iteration++) { std::vector<ELSentence> newSentences; if ( totalIterations < 20 || iteration % (totalIterations / 20) == 0) { std::cout << (((double)iteration) / ((double) totalIterations))*100 << "% done." << std::endl; } sampleStrategy_->sampleSentences(prevModel, reduced, rng, newSentences); // if (iteration == 1) { // std::cout << "initial sampled sentences: "; // std::copy(newSentences.begin(), newSentences.end(), std::ostream_iterator<ELSentence>(std::cout, "\n")); // std::cout << "initial model:"; // std::cout << prevModel; // for (Domain::formula_const_iterator it = prevDomain.formulas_begin(); // it != prevDomain.formulas_end(); // it++) { // std::cout << "formula " << *it << " is satisfied at: " << it->dSatisfied(prevModel, prevDomain) << std::endl; // } // std::cin.get(); // } // make a new domain using new Sentences Domain curDomain; curDomain.setMaxInterval(prevDomain.maxInterval()); for (Domain::fact_const_iterator it = prevDomain.facts_begin(); it != prevDomain.facts_end(); it++) { curDomain.addFact(*it); } for (std::vector<ELSentence>::const_iterator it = newSentences.begin(); it != newSentences.end(); it++) { curDomain.addFormula(*it); } curDomain.addAtoms(prevDomain.atoms_begin(), prevDomain.atoms_end()); // // if (iteration == burnInIterations_ + numSamples_/2) { // std::cout << "ITERATION: " << iteration << std::endl; // std::cout << "curDomain"; // curDomain.printDebugDescription(std::cout); // std::cout << "sampled sentences: "; // std::copy(newSentences.begin(), newSentences.end(), std::ostream_iterator<ELSentence>(std::cout, "\n")); // } boost::unordered_set<Model> curModels = sampleSat(prevModel, curDomain, rng); assert(!curModels.empty()); // choose a random model boost::uniform_int<std::size_t> pickModel(0, curModels.size()-1); boost::unordered_set<Model>::size_type index = pickModel(rng); boost::unordered_set<Model>::const_iterator it = curModels.begin(); while (index > 0) { it++; index--; } // add the model if (iteration >= burnInIterations_) samples_.push_back(*it); prevModel = *it; prevDomain = curDomain; } }