#include "Kernel/Inference.hpp"
#include "Kernel/Ordering.hpp"
#include "Kernel/ColorHelper.hpp"
#include "Saturation/SaturationAlgorithm.hpp"
#include "ForwardLiteralRewriting.hpp"
namespace Inferences
{
void ForwardLiteralRewriting::attach(SaturationAlgorithm* salg)
{
ForwardSimplificationEngine::attach(salg);
_index = salg->getSimplifyingIndex<RewriteRuleIndex>();
}
void ForwardLiteralRewriting::detach()
{
_index = nullptr;
ForwardSimplificationEngine::detach();
}
bool ForwardLiteralRewriting::perform(Clause* cl, Clause*& replacement, ClauseIterator& premises)
{
Ordering& ordering = _salg->getOrdering();
TIME_TRACE("forward literal rewriting");
unsigned clen=cl->length();
for(unsigned i=0;i<clen;i++) {
Literal* lit=(*cl)[i];
auto git = _index->getGeneralizations(lit, lit->isNegative(), true);
while(git.hasNext()) {
auto qr = git.next();
Clause* counterpart=_index->getCounterpart(qr.data->clause);
if(!ColorHelper::compatible(cl->color(), qr.data->clause->color()) ||
!ColorHelper::compatible(cl->color(), counterpart->color()) ) {
continue;
}
if(cl==qr.data->clause || cl==counterpart) {
continue;
}
Literal* rhs0 = (qr.data->literal==(*qr.data->clause)[0]) ? (*qr.data->clause)[1] : (*qr.data->clause)[0];
Literal* rhs = lit->isNegative() ? rhs0 : Literal::complementaryLiteral(rhs0);
auto subs = qr.unifier;
ASS(subs->isIdentityOnQueryWhenResultBound());
ASS(qr.data->literal->containsAllVariablesOf(rhs));
Literal* rhsS = subs->applyToBoundResult(rhs);
if(ordering.compare(lit, rhsS)!=Ordering::GREATER) {
continue;
}
Clause* premise=lit->isNegative() ? qr.data->clause : counterpart;
RStack<Literal*> resLits;
resLits->push(rhsS);
for(Literal* curr : cl->iterLits()) {
if(curr!=lit) {
resLits->push(curr);
}
}
premises = pvi( getSingletonIterator(premise));
replacement = Clause::fromStack(*resLits, SimplifyingInference2(InferenceRule::FORWARD_LITERAL_REWRITING, cl, premise));
return true;
}
}
return false;
}
};