bool TheoryPropagator::PP::propagateFixpoint(Clasp::Solver& s, Clasp::PostPropagator*) { typedef Potassco::AbstractPropagator::ChangeList ChangeList; while (delta_ != trail_.size()) { uint32 dl = s.decisionLevel(); if (undo_.back().level != dl) { s.addUndoWatch(dl, this); undo_.push_back(Undo(dl, delta_)); } ChangeList change = Potassco::toSpan(&trail_[0] + delta_, trail_.size() - delta_); delta_ = trail_.size(); status_ = ClauseCreator::status_open; solver_ = &s; inProp_ = true; bool ok = wrapper_->prop_->propagate(*this, change); inProp_ = false; if (!ok && !s.hasConflict() && (status_ & ClauseCreator::status_asserting) != 0) { if (s.level(clause_[1].var()) < dl && dl != s.backtrackLevel()) { TheoryPropagator::PP::reset(); for (PostPropagator* n = this->next; n; n = n->next) { n->reset(); } dl = s.undoUntil(s.level(clause_[1].var())); } if (!s.isFalse(clause_[0])) { ok = ClauseCreator::create(*solver_, clause_, ccFlags_s | ClauseCreator::clause_no_prepare, Constraint_t::Other); } else { return s.force(clause_[0], this); } } if (s.hasConflict() || !ok || (s.queueSize() && !s.propagateUntil(this))) { if (!s.hasConflict()) { s.setStopConflict(); } return false; } CLASP_FAIL_IF(dl < s.decisionLevel(), "invalid operation in propagation"); } return true; }
void PostPropagator::cancelPropagation() { for (PostPropagator* n = this->next; n; n = n->next) { n->reset(); } }