#include "Lib/Environment.hpp"
#include "Lib/Metaiterators.hpp"
#include "Lib/PairUtils.hpp"
#include "Lib/VirtualIterator.hpp"
#include "Kernel/Clause.hpp"
#include "Kernel/Inference.hpp"
#include "Kernel/RobSubstitution.hpp"
#include "Kernel/SortHelper.hpp"
#include "Kernel/ColorHelper.hpp"
#include "Saturation/SaturationAlgorithm.hpp"
#include "Shell/Options.hpp"
#include "ExtensionalityResolution.hpp"
using namespace std;
using namespace Inferences;
using namespace Lib;
using namespace Kernel;
using namespace Indexing;
using namespace Saturation;
struct ExtensionalityResolution::ForwardPairingFn
{
ForwardPairingFn (ExtensionalityClauseContainer* extClauses)
: _extClauses(extClauses) {}
VirtualIterator<pair<Literal*, ExtensionalityClause> > operator()(Literal* lit)
{
if (!lit->isEquality() || lit->isPositive()) {
return VirtualIterator<pair<Literal*, ExtensionalityClause> >::getEmpty();
}
TermList s = SortHelper::getEqualityArgumentSort(lit);
return pvi(
pushPairIntoRightIterator(
lit,
_extClauses->activeIterator(s)));
}
private:
ExtensionalityClauseContainer* _extClauses;
};
struct ExtensionalityResolution::ForwardUnificationsFn
{
ForwardUnificationsFn() { _subst = RobSubstitutionSP(new RobSubstitution()); }
VirtualIterator<pair<pair<Literal*, ExtensionalityClause>, RobSubstitution*> > operator()(pair<Literal*, ExtensionalityClause> arg)
{
Literal* trmEq = arg.first;
Literal* varEq = arg.second.literal;
SubstIterator unifs = _subst->unifiers(varEq,0,trmEq,1,true);
if (!unifs.hasNext()) {
return VirtualIterator<pair<pair<Literal*, ExtensionalityClause>, RobSubstitution*> >::getEmpty();
}
return pvi(pushPairIntoRightIterator(arg, std::move(unifs)));
}
private:
RobSubstitutionSP _subst;
};
struct ExtensionalityResolution::ForwardResultFn
{
ForwardResultFn(Clause* otherCl, ExtensionalityResolution& parent) : _otherCl(otherCl), _parent(parent) {}
Clause* operator()(pair<pair<Literal*, ExtensionalityClause>, RobSubstitution*> arg)
{
RobSubstitution* subst = arg.second;
Literal* otherLit = arg.first.first;
Clause* extCl = arg.first.second.clause;
Literal* extLit = arg.first.second.literal;
return performExtensionalityResolution(extCl, extLit, _otherCl, otherLit, subst,
_parent.getOptions());
}
private:
Clause* _otherCl;
ExtensionalityResolution& _parent;
};
struct ExtensionalityResolution::NegEqSortFn
{
NegEqSortFn (TermList sort) : _sort(sort) {}
bool operator()(Literal* lit)
{
return lit->isEquality() && lit->isNegative() &&
SortHelper::getEqualityArgumentSort(lit) == _sort;
}
private:
TermList _sort;
};
struct ExtensionalityResolution::BackwardPairingFn
{
BackwardPairingFn (TermList sort) : _sort(sort) {}
VirtualIterator<pair<Clause*, Literal*> > operator()(Clause* cl)
{
return pvi(cl->getSelectedLiteralIterator()
.filter(NegEqSortFn(_sort))
.map([=](auto lit) { return make_pair(cl, lit); }));
}
private:
TermList _sort;
};
struct ExtensionalityResolution::BackwardUnificationsFn
{
BackwardUnificationsFn(Literal* extLit)
: _extLit (extLit) { _subst = RobSubstitutionSP(new RobSubstitution()); }
VirtualIterator<pair<pair<Clause*, Literal*>, RobSubstitution*> > operator()(pair<Clause*, Literal*> arg)
{
Literal* otherLit = arg.second;
SubstIterator unifs = _subst->unifiers(_extLit,0,otherLit,1,true);
if (!unifs.hasNext()) {
return VirtualIterator<pair<pair<Clause*, Literal*>, RobSubstitution*> >::getEmpty();
}
return pvi(pushPairIntoRightIterator(arg, std::move(unifs)));
}
private:
Literal* _extLit;
RobSubstitutionSP _subst;
};
struct ExtensionalityResolution::BackwardResultFn
{
BackwardResultFn(Clause* extCl, Literal* extLit, ExtensionalityResolution& parent) : _extCl(extCl), _extLit(extLit), _parent(parent) {}
Clause* operator()(pair<pair<Clause*, Literal*>, RobSubstitution*> arg)
{
RobSubstitution* subst = arg.second;
Clause* otherCl = arg.first.first;
Literal* otherLit = arg.first.second;
return performExtensionalityResolution(_extCl, _extLit, otherCl, otherLit, subst,
_parent.getOptions());
}
private:
Clause* _extCl;
Literal* _extLit;
ExtensionalityResolution& _parent;
};
Clause* ExtensionalityResolution::performExtensionalityResolution(
Clause* extCl, Literal* extLit,
Clause* otherCl, Literal* otherLit,
RobSubstitution* subst,
const Options& opts)
{
if(!ColorHelper::compatible(extCl->color(),otherCl->color()) ) {
env.statistics->inferencesSkippedDueToColors++;
if(opts.showBlocked()) {
std::cout<<"Blocked extensionality resolution of "<<extCl->toString()<<" and "<<otherCl->toString()<<endl;
}
return 0;
}
RStack<Literal*> resLits;
for (Literal* curr : extCl->iterLits()) {
if (curr != extLit) {
resLits->push(subst->apply(curr, 0));
}
}
for (Literal* curr : otherCl->iterLits()) {
if (curr != otherLit) {
resLits->push(subst->apply(curr, 1));
}
}
return Clause::fromStack(*resLits, GeneratingInference2(InferenceRule::EXTENSIONALITY_RESOLUTION, extCl, otherCl));
}
ClauseIterator ExtensionalityResolution::generateClauses(Clause* premise)
{
ExtensionalityClauseContainer* extClauses = _salg->getExtensionalityClauseContainer();
ClauseIterator backwardIterator;
Literal* extLit = extClauses->addIfExtensionality(premise);
if (extLit) {
auto it1 =
getMapAndFlattenIterator(
_salg->activeClauses(),
BackwardPairingFn(extLit->twoVarEqSort()));
auto it2 = getMapAndFlattenIterator(std::move(it1),BackwardUnificationsFn(extLit));
auto it3 = getMappingIterator(std::move(it2),BackwardResultFn(premise, extLit, *this));
auto it4 = getFilteredIterator(std::move(it3), NonzeroFn());
backwardIterator = pvi(std::move(it4));
} else {
backwardIterator = ClauseIterator::getEmpty();
}
auto it1 = getMapAndFlattenIterator(premise->getSelectedLiteralIterator(),ForwardPairingFn(extClauses));
auto it2 = getMapAndFlattenIterator(std::move(it1),ForwardUnificationsFn());
auto it3 = getMappingIterator(std::move(it2),ForwardResultFn(premise, *this));
auto it4 = getFilteredIterator(std::move(it3), NonzeroFn());
auto it5 = concatIters(std::move(it4),std::move(backwardIterator));
return pvi(std::move(it5));
}