#include "Kernel/Clause.hpp"
#include "Kernel/EqHelper.hpp"
#include "Kernel/Inference.hpp"
#include "Kernel/Term.hpp"
#include "Kernel/TermIterators.hpp"
#include "Kernel/TermIterators.hpp"
#include "CasesSimp.hpp"
namespace Inferences {
using namespace std;
ClauseIterator CasesSimp::performSimplification(Clause* premise, Literal* lit, TermList t) {
ASS(t.isTerm());
TermList lhs = *lit->nthArgument(0);
TermList rhs = *lit->nthArgument(1);
if((t == lhs) || (t == rhs)){
return ClauseIterator::getEmpty();
}
static TermList troo(Term::foolTrue());
static TermList fols(Term::foolFalse());
Literal* litFols = Literal::createEquality(true, t, fols, AtomicSort::boolSort());
Literal* litTroo = Literal::createEquality(true, t, troo, AtomicSort::boolSort());
RStack<Literal*> resLits1;
RStack<Literal*> resLits2;
for (auto curr : premise->iterLits()) {
resLits1->push(curr != lit ? curr : EqHelper::replace(curr, t, troo));
resLits2->push(curr != lit ? curr : EqHelper::replace(curr, t, fols));
}
resLits1->push(litFols);
resLits2->push(litTroo);
return pvi(iterItems(
Clause::fromStack(*resLits1, SimplifyingInference1(InferenceRule::CASES_SIMP, premise)),
Clause::fromStack(*resLits2, SimplifyingInference1(InferenceRule::CASES_SIMP, premise))
));
}
struct CasesSimp::ResultFn
{
ResultFn(Clause* cl, CasesSimp& parent) : _cl(cl), _parent(parent) {}
ClauseIterator operator()(pair<Literal*, TermList> arg)
{
return _parent.performSimplification(_cl, arg.first, arg.second);
}
private:
Clause* _cl;
CasesSimp& _parent;
};
struct CasesSimp::RewriteableSubtermsFn
{
RewriteableSubtermsFn() {}
VirtualIterator<pair<Literal*, TermList> > operator()(Literal* lit)
{
return pvi( pushPairIntoRightIterator(lit,
getUniquePersistentIterator(vi(new BooleanSubtermIt(lit)))));
}
};
Option<ClauseIterator> CasesSimp::simplifyMany(Clause* premise)
{
auto it1 = premise->getLiteralIterator();
auto it2 = getFilteredIterator(it1, isEqualityLit());
auto it3 = getMapAndFlattenIterator(it2,RewriteableSubtermsFn());
auto it4 = getMapAndFlattenIterator(std::move(it3),ResultFn(premise, *this));
if (it4.hasNext()) {
return some(pvi(std::move(it4)));
} else {
return {};
}
}
}