#include "Debug/RuntimeStatistics.hpp"
#include "Lib/Environment.hpp"
#include "Lib/Stack.hpp"
#include "Shell/Statistics.hpp"
#include "SaturationAlgorithm.hpp"
#if OUTPUT_LRS_DETAILS
#include <iostream>
using namespace std;
#endif
#include "ClauseContainer.hpp"
namespace Saturation
{
using namespace Kernel;
using namespace Indexing;
UnprocessedClauseContainer::~UnprocessedClauseContainer()
{
while (!_data.isEmpty()) {
Clause* cl=_data.pop_back();
ASS_EQ(cl->store(), Clause::UNPROCESSED);
cl->setStore(Clause::NONE);
}
}
void UnprocessedClauseContainer::add(Clause* c)
{
_data.push_back(c);
addedEvent.fire(c);
}
Clause* UnprocessedClauseContainer::pop()
{
Clause* res=_data.pop_front();
selectedEvent.fire(res);
return res;
}
void PassiveClauseContainer::updateLimits(long long estReachableCnt)
{
ASS_GE(estReachableCnt,0);
if (estReachableCnt > static_cast<long long>(sizeEstimate())) {
setLimitsToMax();
return;
}
Clause::requestAux();
simulationInit();
long long remains=estReachableCnt;
while (simulationHasNext() && remains > 0)
{
simulationPopSelected();
remains--;
}
bool atLeastOneLimitTightened = setLimitsFromSimulation();
Clause::releaseAux();
if (atLeastOneLimitTightened && env.options->lrsRetroactiveDeletes()) {
onLimitsUpdated();
getSaturationAlgorithm()->getActiveClauseContainer()->onLimitsUpdated(this);
}
}
void ActiveClauseContainer::add(Clause* c)
{
TIME_TRACE("add clause")
ASS(c->store()==Clause::ACTIVE);
ALWAYS(_clauses.insert(c));
addedEvent.fire(c);
}
void ActiveClauseContainer::remove(Clause* c)
{
ASS(c->store()==Clause::ACTIVE);
ALWAYS(_clauses.remove(c));
removedEvent.fire(c);
}
void ActiveClauseContainer::onLimitsUpdated(PassiveClauseContainer* limits)
{
ASS(limits);
if (!limits->mayBeAbleToDiscriminateChildrenOnLimits()) {
return;
}
static Stack<Clause*> toRemove(64);
toRemove.reset();
auto rit = _clauses.iter();
while (rit.hasNext()) {
Clause* cl=rit.next();
ASS(cl);
if (limits->allChildrenNecessarilyExceedLimits(cl, cl->numSelected()))
{
ASS(cl->store()==Clause::ACTIVE);
toRemove.push(cl);
}
}
#if OUTPUT_LRS_DETAILS
if (toRemove.isNonEmpty()) {
cout<<toRemove.size()<<" active deleted\n";
}
#endif
while (toRemove.isNonEmpty()) {
Clause* removed=toRemove.pop();
ASS(removed->store()==Clause::ACTIVE);
RSTAT_CTR_INC("clauses discarded from active on limit update");
env.statistics->discardedNonRedundantClauses++;
remove(removed);
}
}
}