#ifndef __AbstractPassiveClauseContainers__
#define __AbstractPassiveClauseContainers__
#include "Lib/Environment.hpp"
#include "Debug/RuntimeStatistics.hpp"
#include "Debug/Assertion.hpp"
#include "Shell/Statistics.hpp"
#include "Kernel/Clause.hpp"
#include "Kernel/ClauseQueue.hpp"
namespace Saturation {
using namespace Kernel;
template<class T>
class SingleQueuePassiveClauseContainer : public PassiveClauseContainer {
protected:
T _queue;
unsigned _size;
public:
SingleQueuePassiveClauseContainer(bool isOutermost, const Shell::Options& opt, std::string name)
: PassiveClauseContainer(isOutermost, opt, name), _queue(opt), _size(0), _simulationIt(_queue) {}
~SingleQueuePassiveClauseContainer() override {
ClauseQueue::Iterator cit(_queue);
while (cit.hasNext()) {
Clause* cl=cit.next();
ASS(!_isOutermost || cl->store()==Clause::PASSIVE);
cl->setStore(Clause::NONE);
}
}
void add(Clause* cl) override {
ASS(cl->store() == Clause::PASSIVE);
_queue.insert(cl);
_size++;
if (_isOutermost) {
addedEvent.fire(cl);
}
}
void remove(Clause* cl) override {
if (_isOutermost) {
ASS(cl->store()==Clause::PASSIVE);
}
if (_queue.remove(cl)) {
_size--;
}
if (_isOutermost) {
removedEvent.fire(cl);
ASS(cl->store()!=Clause::PASSIVE);
}
}
Clause* popSelected() override {
ASS(!isEmpty());
_size--;
Clause* cl = _queue.pop();
if (_isOutermost) {
selectedEvent.fire(cl);
}
return cl;
}
bool isEmpty() const override { return _queue.isEmpty(); }
unsigned sizeEstimate() const override { return _size; }
protected:
ClauseQueue::Iterator _simulationIt;
static constexpr typename T::OrdVal MAX_LIMIT = T::maxOrdVal;
typename T::OrdVal _curLimit = MAX_LIMIT;
bool setLimit(typename T::OrdVal newLimit) {
bool thighened = newLimit < _curLimit;
_curLimit = newLimit;
return thighened;
}
bool exceedsLimit(Clause* cl) const {
return _curLimit < _queue.getOrdVal(cl);
}
public:
void simulationInit() override {
_simulationIt = ClauseQueue::Iterator(_queue);
}
bool simulationHasNext() override {
return _simulationIt.hasNext();
}
void simulationPopSelected() override {
_simulationIt.next();
}
bool setLimitsToMax() override {
return setLimit(MAX_LIMIT);
}
bool setLimitsFromSimulation() override {
if (_simulationIt.hasNext()) {
return setLimit(_queue.getOrdVal(_simulationIt.next()));
} else {
return setLimitsToMax();
}
}
void onLimitsUpdated() override {
Recycled<Stack<Clause*>> toRemove;
simulationInit(); while (_simulationIt.hasNext()) {
Clause* cl = _simulationIt.next();
if (exceedsLimit(cl)) {
toRemove->push(cl);
} else if (mayBeAbleToDiscriminateChildrenOnLimits() && allChildrenNecessarilyExceedLimits(cl, cl->length())) {
toRemove->push(cl);
}
}
while (toRemove->isNonEmpty()) {
Clause* removed=toRemove->pop();
RSTAT_CTR_INC("clauses discarded from passive on limit update");
env.statistics->discardedNonRedundantClauses++;
remove(removed);
}
}
public:
bool mayBeAbleToDiscriminateChildrenOnLimits() const override { return false; }
bool allChildrenNecessarilyExceedLimits(Clause* cl, unsigned upperBoundNumSelLits) const override { ASSERTION_VIOLATION; return false; }
bool mayBeAbleToDiscriminateClausesUnderConstructionOnLimits() const override { return false; }
bool exceedsAgeLimit(unsigned numPositiveLiterals, const Inference& inference, bool& andThatsIt) const override { ASSERTION_VIOLATION; return false; }
bool exceedsWeightLimit(unsigned w, unsigned numPositiveLiterals, const Inference& inference) const override { ASSERTION_VIOLATION; return false; }
bool limitsActive() const override { return _curLimit != MAX_LIMIT; }
bool exceedsAllLimits(Clause* c) const override { return limitsActive() && exceedsLimit(c); };
};
};
#endif