00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef _MSC_VER
00021 #pragma warning(disable : 4996) // std::copy was declared deprecated
00022 #endif
00023
00024 #include <clasp/dependency_graph.h>
00025 #include <clasp/solver.h>
00026 #include <clasp/clause.h>
00027 #include <clasp/solve_algorithms.h>
00028 #include <clasp/util/timer.h>
00029 namespace Clasp {
00030
00032
00034 SharedDependencyGraph::SharedDependencyGraph(Configuration* cfg) : config_(cfg) {
00035
00036 createAtom(negLit(0), PrgNode::noScc);
00037 VarVec adj; adj.push_back(idMax);
00038 initAtom(sentinel_atom, 0, adj, 0);
00039 }
00040
00041 SharedDependencyGraph::~SharedDependencyGraph() {
00042 for (AtomVec::size_type i = 0; i != atoms_.size(); ++i) {
00043 delete [] atoms_[i].adj_;
00044 }
00045 for (AtomVec::size_type i = 0; i != bodies_.size(); ++i) {
00046 delete [] bodies_[i].adj_;
00047 }
00048 while (!components_.empty()) {
00049 delete components_.back().second;
00050 components_.pop_back();
00051 }
00052 }
00053
00054 bool SharedDependencyGraph::relevantPrgAtom(const Solver& s, PrgAtom* a) const {
00055 return a->inUpper() && a->scc() != PrgNode::noScc && !s.isFalse(a->literal());
00056 }
00057 bool SharedDependencyGraph::relevantPrgBody(const Solver& s, PrgBody* b) const {
00058 return !s.isFalse(b->literal());
00059 }
00060
00061
00062
00063
00064
00065
00066
00067 void SharedDependencyGraph::addSccs(LogicProgram& prg, const AtomList& sccAtoms, const NonHcfSet& nonHcfs) {
00068
00069 atoms_.reserve(atoms_.size() + sccAtoms.size());
00070 AtomList::size_type numBodies = 0;
00071 SharedContext& ctx = *prg.ctx();
00072 for (AtomList::size_type i = 0, end = sccAtoms.size(); i != end; ++i) {
00073 PrgAtom* a = sccAtoms[i];
00074 if (relevantPrgAtom(*ctx.master(), a)) {
00075
00076 a->resetId(createAtom(a->literal(), a->scc()), true);
00077
00078 ctx.setFrozen(a->var(), true);
00079 numBodies += a->supports();
00080 }
00081 }
00082
00083 VarVec adj, ext;
00084 bodies_.reserve(bodies_.size() + numBodies/2);
00085 PrgBody* prgBody; PrgDisj* prgDis;
00086 for (AtomList::size_type i = 0, end = sccAtoms.size(); i != end; ++i) {
00087 PrgAtom* a = sccAtoms[i];
00088 if (relevantPrgAtom(*ctx.master(), a)) {
00089 uint32 prop = 0;
00090 for (PrgAtom::sup_iterator it = a->supps_begin(), endIt = a->supps_end(); it != endIt; ++it) {
00091 assert(it->isBody() || it->isDisj());
00092 NodeId bId= PrgNode::maxVertex;
00093 if (it->isBody() && !it->isGamma()) {
00094 prgBody = prg.getBody(it->node());
00095 bId = relevantPrgBody(*ctx.master(), prgBody) ? addBody(prg, prgBody) : PrgNode::maxVertex;
00096 }
00097 else if (it->isDisj()) {
00098 prgDis = prg.getDisj(it->node());
00099 bId = addDisj(prg, prgDis);
00100 prop |= AtomNode::property_in_disj;
00101 ctx.setInDisj(a->var(), true);
00102 }
00103 if (bId != PrgNode::maxVertex) {
00104 if (!bodies_[bId].seen()) {
00105 bodies_[bId].seen(true);
00106 adj.push_back(bId);
00107 }
00108 if (it->isChoice()) {
00109
00110 prop |= AtomNode::property_in_choice;
00111 }
00112 }
00113 }
00114 uint32 nPred= (uint32)adj.size();
00115 for (PrgAtom::dep_iterator it = a->deps_begin(), endIt = a->deps_end(); it != endIt; ++it) {
00116 if (!it->sign()) {
00117 PrgBody* prgBody = prg.getBody(it->var());
00118 if (relevantPrgBody(*ctx.master(), prgBody) && prgBody->scc(prg) == a->scc()) {
00119 NodeId bodyId = addBody(prg, prgBody);
00120 if (!bodies_[bodyId].extended()) {
00121 adj.push_back(bodyId);
00122 }
00123 else {
00124 ext.push_back(bodyId);
00125 ext.push_back(bodies_[bodyId].get_pred_idx(a->id()));
00126 assert(bodies_[bodyId].get_pred(ext.back()) == a->id());
00127 prop |= AtomNode::property_in_ext;
00128 }
00129 }
00130 }
00131 }
00132 if (!ext.empty()) {
00133 adj.push_back(idMax);
00134 adj.insert(adj.end(), ext.begin(), ext.end());
00135 }
00136 adj.push_back(idMax);
00137 initAtom(a->id(), prop, adj, nPred);
00138 adj.clear(); ext.clear();
00139 }
00140 }
00141
00142 for (NonHcfIter it = nonHcfBegin(), end = nonHcfEnd(); it != end; ++it) {
00143 it->second->update(ctx);
00144 }
00145
00146 for (NonHcfSet::const_iterator it = nonHcfs.begin() + components_.size(), end = nonHcfs.end(); it != end; ++it) {
00147 addNonHcf(ctx, *it);
00148 }
00149 }
00150
00151 uint32 SharedDependencyGraph::createAtom(Literal lit, uint32 aScc) {
00152 NodeId id = (uint32)atoms_.size();
00153 atoms_.push_back(AtomNode());
00154 AtomNode& ua = atoms_.back();
00155 ua.lit = lit;
00156 ua.scc = aScc;
00157 return id;
00158 }
00159
00160 void SharedDependencyGraph::initAtom(uint32 id, uint32 prop, const VarVec& adj, uint32 numPreds) {
00161 AtomNode& ua = atoms_[id];
00162 ua.setProperties(prop);
00163 ua.adj_ = new NodeId[adj.size()];
00164 ua.sep_ = ua.adj_ + numPreds;
00165 NodeId* sExt = ua.adj_;
00166 NodeId* sSame= sExt + numPreds;
00167 uint32 aScc = ua.scc;
00168 for (VarVec::const_iterator it = adj.begin(), end = adj.begin()+numPreds; it != end; ++it) {
00169 BodyNode& bn = bodies_[*it];
00170 if (bn.scc != aScc) { *sExt++ = *it; }
00171 else { *--sSame= *it; }
00172 bn.seen(false);
00173 }
00174 std::reverse(sSame, ua.adj_ + numPreds);
00175 std::copy(adj.begin()+numPreds, adj.end(), ua.sep_);
00176 }
00177
00178 uint32 SharedDependencyGraph::createBody(PrgBody* b, uint32 bScc) {
00179 NodeId id = (uint32)bodies_.size();
00180 bodies_.push_back(BodyNode(b, bScc));
00181 return id;
00182 }
00183
00184
00185 uint32 SharedDependencyGraph::addBody(const LogicProgram& prg, PrgBody* b) {
00186 if (b->seen()) {
00187 VarVec preds, atHeads;
00188 uint32 bScc = b->scc(prg);
00189 NodeId bId = createBody(b, bScc);
00190 addPreds(prg, b, bScc, preds);
00191 addHeads(prg, b, atHeads);
00192 initBody(bId, preds, atHeads);
00193 b->resetId(bId, false);
00194 prg.ctx()->setFrozen(b->var(), true);
00195 }
00196 return b->id();
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206 void SharedDependencyGraph::addPreds(const LogicProgram& prg, PrgBody* b, uint32 bScc, VarVec& preds) const {
00207 if (bScc == PrgNode::noScc) { preds.clear(); return; }
00208 const bool weights = b->type() == Asp::BodyInfo::SUM_BODY;
00209 for (uint32 i = 0; i != b->size() && !b->goal(i).sign(); ++i) {
00210 PrgAtom* pred = prg.getAtom(b->goal(i).var());
00211 if (relevantPrgAtom(*prg.ctx()->master(), pred) && pred->scc() == bScc) {
00212 preds.push_back( pred->id() );
00213 if (weights) { preds.push_back(b->weight(i)); }
00214 }
00215 }
00216 if (b->type() != Asp::BodyInfo::NORMAL_BODY) {
00217 preds.insert(preds.begin(), b->bound());
00218 preds.push_back(idMax);
00219 for (uint32 n = 0; n != b->size(); ++n) {
00220 PrgAtom* pred = prg.getAtom(b->goal(n).var());
00221 bool ext = b->goal(n).sign() || pred->scc() != bScc;
00222 Literal lit = b->goal(n).sign() ? ~pred->literal() : pred->literal();
00223 if (ext && !prg.ctx()->master()->isFalse(lit)) {
00224 preds.push_back(lit.asUint());
00225 if (weights) { preds.push_back(b->weight(n)); }
00226 }
00227 }
00228 }
00229 preds.push_back(idMax);
00230 }
00231
00232
00233
00234 uint32 SharedDependencyGraph::addHeads(const LogicProgram& prg, PrgBody* b, VarVec& heads) const {
00235 for (PrgBody::head_iterator it = b->heads_begin(), end = b->heads_end(); it != end; ++it) {
00236 if (it->isAtom() && !it->isGamma()) {
00237 PrgAtom* a = prg.getAtom(it->node());
00238 if (relevantPrgAtom(*prg.ctx()->master(), a)) {
00239 heads.push_back(a->id());
00240 }
00241 }
00242 else if (it->isDisj()) {
00243 assert(prg.getDisj(it->node())->inUpper() && prg.getDisj(it->node())->supports() == 1);
00244 PrgDisj* d = prg.getDisj(it->node());
00245
00246 heads.push_back(sentinel_atom);
00247 getAtoms(prg, d, heads);
00248 heads.push_back(sentinel_atom);
00249 }
00250 }
00251 return heads.size();
00252 }
00253
00254
00255 uint32 SharedDependencyGraph::getAtoms(const LogicProgram& prg, PrgDisj* d, VarVec& atoms) const {
00256 uint32 scc = PrgNode::noScc;
00257 for (PrgDisj::atom_iterator it = d->begin(), end = d->end(); it != end; ++it) {
00258 PrgAtom* a = prg.getAtom(it->node());
00259 if (relevantPrgAtom(*prg.ctx()->master(), a)) {
00260 assert(scc == PrgNode::noScc || scc == a->scc());
00261 atoms.push_back(a->id());
00262 scc = a->scc();
00263 }
00264 }
00265 return scc;
00266 }
00267
00268
00269 void SharedDependencyGraph::initBody(uint32 id, const VarVec& preds, const VarVec& atHeads) {
00270 BodyNode* bn = &bodies_[id];
00271 uint32 nSuccs= atHeads.size();
00272 bn->adj_ = new NodeId[nSuccs + preds.size()];
00273 bn->sep_ = bn->adj_ + nSuccs;
00274 NodeId* sSame= bn->adj_;
00275 NodeId* sExt = sSame + nSuccs;
00276 uint32 bScc = bn->scc;
00277 uint32 hScc = PrgNode::noScc;
00278 uint32 disj = 0;
00279 for (VarVec::const_iterator it = atHeads.begin(), end = atHeads.end(); it != end;) {
00280 if (*it) {
00281 hScc = getAtom(*it).scc;
00282 if (hScc == bScc) { *sSame++ = *it++; }
00283 else { *--sExt = *it++; }
00284 }
00285 else {
00286 hScc = getAtom(it[1]).scc; ++disj;
00287 if (hScc == bScc) { *sSame++ = *it++; while ( (*sSame++ = *it++) ) { ; } }
00288 else { *--sExt = *it++; while ( (*--sExt = *it++) ) { ; } }
00289 }
00290 }
00291 std::copy(preds.begin(), preds.end(), bn->sep_);
00292 bn->sep_ += bn->extended();
00293 if (disj) { bodies_[id].data |= BodyNode::flag_has_delta; }
00294 }
00295
00296 uint32 SharedDependencyGraph::addDisj(const LogicProgram& prg, PrgDisj* d) {
00297 assert(d->inUpper() && d->supports() == 1);
00298 if (d->seen()) {
00299 PrgBody* prgBody = prg.getBody(d->supps_begin()->node());
00300 uint32 bId = PrgNode::maxVertex;
00301 if (relevantPrgBody(*prg.ctx()->master(), prgBody)) {
00302 bId = addBody(prg, prgBody);
00303 }
00304 d->resetId(bId, false);
00305 }
00306 return d->id();
00307 }
00308
00309 void SharedDependencyGraph::addNonHcf(SharedContext& ctx, uint32 scc) {
00310 VarVec sccAtoms, sccBodies;
00311
00312 for (uint32 i = 0; i != numAtoms(); ++i) {
00313 if (getAtom(i).scc == scc) {
00314 sccAtoms.push_back(i);
00315 atoms_[i].set(AtomNode::property_in_non_hcf);
00316 }
00317 }
00318
00319 const Solver& generator = *ctx.master(); (void)generator;
00320 for (uint32 i = 0; i != sccAtoms.size(); ++i) {
00321 const AtomNode& a = getAtom(sccAtoms[i]);
00322 for (const NodeId* bodyIt = a.bodies_begin(), *bodyEnd = a.bodies_end(); bodyIt != bodyEnd; ++bodyIt) {
00323 BodyNode& B = bodies_[*bodyIt];
00324 if (!B.seen()) {
00325 assert(generator.value(B.lit.var()) != value_free || !generator.seen(B.lit));
00326 sccBodies.push_back(*bodyIt);
00327 B.seen(true);
00328 }
00329 }
00330 }
00331 for (uint32 i = 0; i != sccBodies.size(); ++i) { bodies_[sccBodies[i]].seen(false); }
00332 components_.push_back( ComponentPair(scc, new NonHcfComponent(*this, ctx, scc, sccAtoms, sccBodies)) );
00333 }
00334 void SharedDependencyGraph::accuStats() const {
00335 for (NonHcfIter it = nonHcfBegin(), end = nonHcfEnd(); it != end; ++it) {
00336 it->second->prg_->accuStats();
00337 }
00338 }
00340
00342 class SharedDependencyGraph::NonHcfComponent::ComponentMap {
00343 public:
00344 ComponentMap() { static_assert(sizeof(Mapping) == sizeof(uint64), "Invalid padding!"); }
00345 struct Mapping {
00346 explicit Mapping(NodeId id) : node(id), varOff(0), varUsed(0), isEq(0) { }
00347 uint32 node;
00348 uint32 varOff : 30;
00349 uint32 varUsed: 1;
00350 uint32 isEq : 1;
00351 Var var() const { return varOff * varUsed; }
00352 Literal atPos() const { return posLit(var()); }
00353 Literal atAux() const { return posLit(varOff+1); }
00354 Literal atUnf() const { return posLit(varOff+2); }
00355 Literal bodyAux() const { return posLit(var()); }
00356 bool operator<(const Mapping& other) const { return node < other.node; }
00357 };
00358 typedef SharedDependencyGraph SccGraph;
00359 typedef PodVector<Mapping>::type NodeMap;
00360 typedef NodeMap::iterator MapIt;
00361 typedef NodeMap::const_iterator MapIt_c;
00362 typedef std::pair<MapIt_c, MapIt_c> MapRange;
00363 void addVars(Solver& generator, const SccGraph& dep, const VarVec& atoms, const VarVec& bodies, SharedContext& out);
00364 void addAtomConstraints(SharedContext& out);
00365 void addBodyConstraints(const Solver& generator, const SccGraph& dep, uint32 scc, SharedContext& out);
00366 void mapGeneratorAssignment(const Solver& generator, const SccGraph& dep, LitVec& out) const;
00367 void mapTesterModel(const Solver& tester, VarVec& out) const;
00368 MapRange atoms() const { return MapRange(mapping.begin(), mapping.begin() + numAtoms); }
00369 MapRange bodies()const { return MapRange(mapping.begin() + numAtoms, mapping.end()); }
00370 MapIt_c findAtom(NodeId nodeId) const { return std::lower_bound(mapping.begin(), mapping.begin()+numAtoms, Mapping(nodeId)); }
00371 NodeMap mapping;
00372 uint32 numAtoms;
00373 };
00374
00375
00376
00377
00378
00379
00380
00381
00382 void SharedDependencyGraph::NonHcfComponent::ComponentMap::addVars(Solver& generator, const SccGraph& dep, const VarVec& atoms, const VarVec& bodies, SharedContext& comp) {
00383 mapping.reserve(atoms.size() + bodies.size());
00384 for (VarVec::const_iterator it = atoms.begin(), end = atoms.end(); it != end; ++it) {
00385 const AtomNode& at = dep.getAtom(*it);
00386 Literal gen = at.lit;
00387 if (generator.isFalse(gen)) { continue; }
00388 Mapping map(*it);
00389 map.varUsed = !generator.isTrue(gen) || generator.level(gen.var()) > 0;
00390 map.varOff = map.varUsed ? comp.addVar(Var_t::atom_var) : comp.numVars();
00391
00392 comp.addVar(Var_t::atom_var);
00393 comp.addVar(Var_t::atom_var);
00394 comp.setFrozen(map.atUnf().var(), true);
00395 comp.setFrozen(map.atPos().var(), true);
00396 mapping.push_back(map);
00397 }
00398 numAtoms = (uint32)mapping.size();
00399 std::stable_sort(mapping.begin(), mapping.end());
00400
00401 for (VarVec::const_iterator it = bodies.begin(), end = bodies.end(); it != end; ++it) {
00402 Literal gen = dep.getBody(*it).lit;
00403 if (generator.isFalse(gen)) { continue; }
00404 Mapping map(*it);
00405 map.varUsed = !generator.isTrue(gen) || generator.level(gen.var()) > 0;
00406 if (map.varUsed && !generator.seen(gen)) {
00407 map.varOff= comp.addVar(Var_t::atom_var);
00408 generator.markSeen(gen);
00409 }
00410 else {
00411 map.isEq = 1;
00412 map.varOff= comp.numVars()+1;
00413 if (map.varUsed) {
00414 for (MapRange r = this->bodies(); r.first != r.second;) {
00415 --r.second;
00416 if (dep.getBody(r.second->node).lit == gen) {
00417 map.varOff = r.second->varOff;
00418 break;
00419 }
00420 }
00421 assert(map.varOff <= comp.numVars());
00422 }
00423 }
00424 comp.setFrozen(map.bodyAux().var(), true);
00425 mapping.push_back(map);
00426 }
00427 for (MapRange r = this->bodies(); r.first != r.second; ++r.first) {
00428 if (!r.first->isEq) {
00429 Var v = dep.getBody(r.first->node).lit.var();
00430 generator.clearSeen(v);
00431 }
00432 }
00433 }
00434
00435
00436
00437
00438
00439
00440
00441 void SharedDependencyGraph::NonHcfComponent::ComponentMap::addAtomConstraints(SharedContext& comp) {
00442 ClauseCreator cc1(comp.master()), cc2(comp.master());
00443 cc1.addDefaultFlags(ClauseCreator::clause_force_simplify);
00444 cc1.start();
00445 for (MapRange r = atoms(); r.first != r.second; ++r.first) {
00446 const Mapping& m = *r.first;
00447 cc1.add(m.atUnf());
00448 cc2.start().add(~m.atPos()).add(m.atUnf()).add(~m.atAux()).end();
00449 cc2.start().add(m.atAux()).add(m.atPos()).end();
00450 cc2.start().add(m.atAux()).add(~m.atUnf()).end();
00451 }
00452 cc1.end();
00453 }
00454
00455
00456
00457
00458
00459 void SharedDependencyGraph::NonHcfComponent::ComponentMap::addBodyConstraints(const Solver& generator, const SccGraph& dep, uint32 scc, SharedContext& comp) {
00460 ClauseCreator cc(comp.master());
00461 cc.addDefaultFlags(ClauseCreator::clause_force_simplify);
00462 ClauseCreator dc(comp.master());
00463 MapIt j = mapping.begin() + numAtoms;
00464 for (MapRange r = bodies(); r.first != r.second; ++r.first) {
00465 const BodyNode& B = dep.getBody(r.first->node);
00466 if (generator.isFalse(B.lit)) { continue; }
00467 if (B.extended()) { throw std::runtime_error("Extended bodies not supported - use '--trans-ext=weight'"); }
00468 for (const NodeId* hIt = B.heads_begin(), *hEnd = B.heads_end(); hIt != hEnd; ++hIt) {
00469 uint32 hScc = *hIt ? dep.getAtom(*hIt).scc : dep.getAtom(hIt[1]).scc;
00470 if (hScc != scc) {
00471
00472 if (!*hIt) { do { ++hIt; } while (*hIt); }
00473 continue;
00474 }
00475
00476 cc.start().add(~r.first->bodyAux());
00477 if (B.scc == scc) {
00478 for (const NodeId* aIt = B.preds(); *aIt != idMax; ++aIt) {
00479 MapIt_c atMapped = findAtom(*aIt);
00480 cc.add(atMapped->atUnf());
00481 }
00482 }
00483 if (*hIt) {
00484 MapIt_c atMapped = findAtom(*hIt);
00485 assert(atMapped != atoms().second);
00486 cc.add(~atMapped->atUnf());
00487 cc.end();
00488 }
00489 else {
00490 const NodeId* dHead = ++hIt;
00491 for (; *hIt; ++hIt) {
00492 dc.start();
00493 dc = cc;
00494 MapIt_c atMapped = findAtom(*hIt);
00495 dc.add(~atMapped->atUnf());
00496 for (const NodeId* other = dHead; *other; ++other) {
00497 if (*other != *hIt) {
00498 assert(dep.getAtom(*other).scc == scc);
00499 atMapped = findAtom(*other);
00500 dc.add(~atMapped->atAux());
00501 }
00502 }
00503 dc.end();
00504 }
00505 }
00506 }
00507 if (r.first->isEq == 0) { *j++ = *r.first; }
00508 }
00509 mapping.erase(j, mapping.end());
00510 }
00511
00512
00513 void SharedDependencyGraph::NonHcfComponent::ComponentMap::mapGeneratorAssignment(const Solver& s, const SccGraph& dep, LitVec& out) const {
00514 Literal gen;
00515 out.clear(); out.reserve(mapping.size());
00516 for (MapRange r = atoms(); r.first != r.second; ++r.first) {
00517 const Mapping& at = *r.first;
00518 assert(at.varUsed || at.atPos() == posLit(0));
00519 if (at.varUsed) {
00520 gen = dep.getAtom(at.node).lit;
00521 out.push_back(at.atPos());
00522 if (!s.isTrue(gen)) {
00523 out.back() = ~at.atPos();
00524 if (s.isFalse(gen)) { out.push_back(~at.atUnf()); }
00525 }
00526 }
00527 }
00528 for (MapRange r = bodies(); r.first != r.second; ++r.first) {
00529 gen = dep.getBody(r.first->node).lit;
00530 out.push_back(!s.isFalse(gen) ? r.first->bodyAux() : ~r.first->bodyAux());
00531 }
00532 }
00533
00534 void SharedDependencyGraph::NonHcfComponent::ComponentMap::mapTesterModel(const Solver& s, VarVec& out) const {
00535 assert(s.numFreeVars() == 0);
00536 out.clear();
00537 for (MapRange r = atoms(); r.first != r.second; ++r.first) {
00538 if (s.isTrue(r.first->atUnf())) {
00539 out.push_back(r.first->node);
00540 }
00541 }
00542 }
00544
00546 SolveTestEvent::SolveTestEvent(const Solver& s, uint32 a_scc, bool part)
00547 : SolveEvent<SolveTestEvent>(s, Event::verbosity_max)
00548 , result(-1), scc(a_scc), partial(part) {
00549 confDelta = s.stats.conflicts;
00550 choiceDelta = s.stats.choices;
00551 time = 0.0;
00552 }
00553 uint64 SolveTestEvent::choices() const {
00554 return solver->stats.choices - choiceDelta;
00555 }
00556 uint64 SolveTestEvent::conflicts() const {
00557 return solver->stats.conflicts - confDelta;
00558 }
00559
00560 SharedDependencyGraph::NonHcfComponent::NonHcfComponent(const SharedDependencyGraph& dep, SharedContext& genCtx, uint32 scc, const VarVec& atoms, const VarVec& bodies)
00561 : prg_(new SharedContext())
00562 , comp_(new ComponentMap()){
00563 Solver& generator = *genCtx.master();
00564 prg_->setConcurrency(genCtx.concurrency());
00565 prg_->setConfiguration(dep.nonHcfConfig(), false);
00566 comp_->addVars(generator, dep, atoms, bodies, *prg_);
00567 prg_->startAddConstraints();
00568 comp_->addAtomConstraints(*prg_);
00569 comp_->addBodyConstraints(generator, dep, scc, *prg_);
00570 prg_->enableStats(generator.stats.level());
00571 prg_->endInit(true);
00572 }
00573
00574 SharedDependencyGraph::NonHcfComponent::~NonHcfComponent() {
00575 delete prg_;
00576 delete comp_;
00577 }
00578
00579 void SharedDependencyGraph::NonHcfComponent::update(const SharedContext& generator) {
00580 prg_->enableStats(generator.master()->stats.level());
00581 for (uint32 i = 0; generator.hasSolver(i); ++i) {
00582 if (!prg_->hasSolver(i)) { prg_->attach(prg_->addSolver()); }
00583 else { prg_->initStats(*prg_->solver(i)); }
00584 }
00585 }
00586
00587 void SharedDependencyGraph::NonHcfComponent::assumptionsFromAssignment(const Solver& s, LitVec& assume) const {
00588 assert(s.sharedContext()->sccGraph.get() != 0);
00589 comp_->mapGeneratorAssignment(s, *s.sharedContext()->sccGraph, assume);
00590 }
00591
00592 bool SharedDependencyGraph::NonHcfComponent::test(uint32 scc, const Solver& generator, const LitVec& assume, VarVec& unfoundedOut) const {
00593 assert(generator.id() < prg_->concurrency() && "Invalid id!");
00594
00595
00596 struct Tester : MessageHandler {
00597 Tester(Solver& s, MessageHandler* gen) : solver(&s), generator(gen) { if (gen) { s.addPost(this); } }
00598 ~Tester() { if (generator) { solver->removePost(this); } }
00599 bool handleMessages() { return generator->handleMessages(); }
00600 bool propagateFixpoint(Solver&, PostPropagator*) { return Tester::handleMessages() || !terminate(); }
00601 bool terminate() { solver->setStopConflict(); return true; }
00602 int test(const LitVec& assume) {
00603 return int(BasicSolve(*solver).satisfiable(assume, solver->stats.choices == 0) == false);
00604 }
00605 Solver* solver;
00606 MessageHandler* generator;
00607 } tester(*prg_->solver(generator.id()), static_cast<MessageHandler*>(generator.getPost(PostPropagator::priority_reserved_msg)));
00608 SolveTestEvent ev(*tester.solver, scc, generator.numFreeVars() != 0);
00609 tester.solver->stats.addTest(ev.partial);
00610 generator.sharedContext()->report(ev);
00611 ev.time = ThreadTime::getTime();
00612 if ((ev.result = tester.test(assume)) == 0) {
00613 tester.solver->stats.addModel(tester.solver->decisionLevel());
00614 comp_->mapTesterModel(*tester.solver, unfoundedOut);
00615 }
00616 ev.time = ThreadTime::getTime() - ev.time;
00617 tester.solver->stats.addCpuTime(ev.time);
00618 generator.sharedContext()->report(ev);
00619 return ev.result != 0;
00620 }
00621 }