#include "Lib/DArray.hpp"
#include "Lib/Metaiterators.hpp"
#include "Debug/TimeProfiling.hpp"
#include "Kernel/Term.hpp"
#include "Kernel/Clause.hpp"
#include "Kernel/MLMatcher.hpp"
#include "Kernel/Inference.hpp"
#include "Kernel/RobSubstitution.hpp"
#include "Indexing/LiteralMiniIndex.hpp"
#include "Condensation.hpp"
namespace Inferences {
using namespace std;
using namespace Lib;
using namespace Kernel;
using namespace Indexing;
using namespace Saturation;
Clause* Condensation::simplify(Clause* cl)
{
TIME_TRACE("condensation");
unsigned clen=cl->length();
if(clen<=1) {
return cl;
}
unsigned newLen=clen-1;
static DArray<Literal*> newLits(32);
static DArray<LiteralList*> alts(32);
LiteralMiniIndex cmi(cl);
CombinationIterator<unsigned> pairIt(0, clen);
while(pairIt.hasNext()) {
pair<unsigned,unsigned> lpair=pairIt.next();
unsigned l1Index=lpair.first;
unsigned l2Index=lpair.second;
if(l1Index==l2Index) {
continue;
}
Literal* l1=(*cl)[l1Index];
Literal* l2=(*cl)[l2Index];
newLits.ensure(newLen);
RobSubstitution subst0;
SubstIterator sit=subst0.unifiers(l1,0,l2,0,false);
while(sit.hasNext()) {
RobSubstitution* subst=sit.next();
alts.init(newLen,0);
bool success=false;
unsigned next=0;
{
Literal* lit=subst->apply(l1,0);
newLits[next] = lit;
LiteralMiniIndex::InstanceIterator iit(cmi, lit, false);
if(!iit.hasNext()) {
goto match_fin;
}
while(iit.hasNext()) {
LiteralList::push(iit.next(), alts[next]);
}
next++;
}
for(unsigned i=0;i<clen;i++) {
if(i!=l1Index && i!=l2Index) {
Literal* lit=subst->apply((*cl)[i],0);
newLits[next] = lit;
LiteralMiniIndex::InstanceIterator iit(cmi, lit, false);
if(!iit.hasNext()) {
goto match_fin;
}
while(iit.hasNext()) {
LiteralList::push(iit.next(), alts[next]);
}
next++;
}
}
success=MLMatcher::canBeMatched(newLits.array(), newLen, cl,alts.array(),0,false);
match_fin:
for(unsigned i=0;i<newLen;i++) {
LiteralList::destroy(alts[i]);
}
if(success) {
return Clause::fromArray(newLits.begin(), newLen, SimplifyingInference1(InferenceRule::CONDENSATION, cl));
}
}
}
return cl;
}
}