#include "Lib/Environment.hpp"
#include "Debug/TimeProfiling.hpp"
#include "Kernel/Clause.hpp"
#include "Kernel/Signature.hpp"
#include "ConsequenceFinder.hpp"
#include "SaturationAlgorithm.hpp"
namespace Saturation
{
using namespace std;
using namespace Lib;
using namespace Kernel;
void ConsequenceFinder::init(SaturationAlgorithm* sa)
{
_sa=sa;
ClauseContainer* cc=_sa->getSimplifyingClauseContainer();
_sdInsertion = cc->addedEvent.subscribe(this,&ConsequenceFinder::onClauseInserted);
_sdRemoval = cc->removedEvent.subscribe(this,&ConsequenceFinder::onClauseRemoved);
}
ConsequenceFinder::~ConsequenceFinder()
{
_sdInsertion->unsubscribe();
_sdRemoval->unsubscribe();
}
void ConsequenceFinder::onNewPropositionalClause(Clause* cl)
{
TIME_TRACE(TimeTrace::CONSEQUENCE_FINDING);
Clause* dlrCl=_dlr.simplify(cl);
bool dlrSimplified=dlrCl!=cl;
if(dlrSimplified) {
dlrCl->destroyIfUnnecessary();
return;
}
if(!cl->noSplits() || !_td.simplify(cl)) {
return;
}
Literal* pos=0;
bool horn=true;
for (auto l : cl->iterLits()) {
if(!env.signature->getPredicate(l->functor())->label()) {
return;
}
if(l->isPositive()) {
if(pos) {
horn=false;
}
else {
pos=l;
}
}
}
std::cout << "Pure cf clause: " << cl->toNiceString() <<endl;
if(!horn || !pos) {
return;
}
unsigned red=pos->functor(); if(_redundant[red]) {
return;
}
_redundant[red]=true;
_redundantsToHandle.push(red);
std::cout << "Consequence found: " << env.signature->predicateName(red) << endl;
}
void ConsequenceFinder::onAllProcessed()
{
TIME_TRACE(TimeTrace::CONSEQUENCE_FINDING);
while(_redundantsToHandle.isNonEmpty()) {
unsigned red=_redundantsToHandle.pop();
ClauseSL* rlist=_index[red];
if(rlist) {
_index[red]=0;
while(rlist->isNonEmpty()) {
Clause* rcl=rlist->pop();
(void)(rcl->store()!=Clause::UNPROCESSED && rcl->store()!=Clause::NONE);
if(rcl->store()) {
continue;
}
_sa->removeActiveOrPassiveClause(rcl);
}
delete rlist;
}
}
}
bool ConsequenceFinder::isRedundant(Clause* cl)
{
for (auto l : cl->iterLits()) {
unsigned fn = l->functor();
if(!env.signature->getPredicate(fn)->label()) {
continue;
}
if(_redundant[fn]) {
return true;
}
}
return false;
}
void ConsequenceFinder::onClauseInserted(Clause* cl)
{
TIME_TRACE(TimeTrace::CONSEQUENCE_FINDING);
bool red=false;
for (auto l : cl->iterLits()) {
unsigned fn = l->functor();
if(!env.signature->getPredicate(fn)->label()) {
continue;
}
if(_redundant[fn]) {
red=true;
}
else {
indexClause(fn, cl, true);
}
}
if(red) {
}
}
void ConsequenceFinder::onClauseRemoved(Clause* cl)
{
TIME_TRACE(TimeTrace::CONSEQUENCE_FINDING);
for (auto l : cl->iterLits()) {
unsigned fn = l->functor();
if(!env.signature->getPredicate(fn)->label()) {
continue;
}
if(!_redundant[fn]) {
indexClause(fn, cl, false);
}
}
}
void ConsequenceFinder::indexClause(unsigned indexNum, Clause* cl, bool add)
{
if(add) {
if(!_index[indexNum]) {
_index[indexNum]=new ClauseSL();
}
_index[indexNum]->insert(cl);
}
else {
ASS(_index[indexNum]);
_index[indexNum]->remove(cl);
}
}
}