#include "Kernel/Clause.hpp"
#include "Kernel/EqHelper.hpp"
#include "Kernel/SubstHelper.hpp"
#include "Kernel/Term.hpp"
#include "Kernel/Ordering.hpp"
#include "Kernel/TermIterators.hpp"
#include "Kernel/Ordering.hpp"
#include "Shell/Options.hpp"
#include "DemodulationHelper.hpp"
namespace Inferences {
using namespace Kernel;
DemodulationHelper::DemodulationHelper(const Options& opts, const Ordering* ord)
: _redundancyCheck(opts.demodulationRedundancyCheck() != Options::DemodulationRedundancyCheck::OFF),
_encompassing(opts.demodulationRedundancyCheck() == Options::DemodulationRedundancyCheck::ENCOMPASS),
_ord(ord)
{
}
bool DemodulationHelper::redundancyCheckNeededForPremise(Clause* rwCl, Literal* rwLit, TermList rwTerm) const
{
if (!_redundancyCheck) {
return false;
}
if (!rwLit->isEquality() || (rwTerm!=*rwLit->nthArgument(0) && rwTerm!=*rwLit->nthArgument(1))) {
return false;
}
return !_encompassing || (rwLit->isPositive() && (rwCl->length() == 1));
}
bool DemodulationHelper::isRenamingOn(const SubstApplicator* applicator, TermList t)
{
DHSet<TermList> renamingDomain;
DHSet<TermList> renamingRange;
VariableIterator it(t);
while(it.hasNext()) {
TermList v = it.next();
ASS(v.isVar());
if (!renamingDomain.insert(v)) {
continue;
}
TermList vSubst = (*applicator)(v.var());
if (!vSubst.isVar()) {
return false;
}
if (!renamingRange.insert(vSubst)) {
return false;
}
}
return true;
}
bool DemodulationHelper::isPremiseRedundant(Clause* rwCl, Literal* rwLit, TermList rwTerm,
TermList tgtTerm, TermList eqLHS, const SubstApplicator* eqApplicator) const
{
ASS(redundancyCheckNeededForPremise(rwCl, rwLit, rwTerm));
TermList other=EqHelper::getOtherEqualitySide(rwLit, rwTerm);
if (_ord->compare(tgtTerm, other) == Ordering::LESS) {
return true;
}
if (_encompassing) {
return !isRenamingOn(eqApplicator,eqLHS);
}
if (rwCl->length()==1) {
return false;
}
TermList eqSort = SortHelper::getEqualityArgumentSort(rwLit);
Literal* eqLitS=Literal::createEquality(true, rwTerm, tgtTerm, eqSort);
return rwCl->iterLits().any([rwLit,this,eqLitS](Literal* lit) {
return lit != rwLit && _ord->compare(eqLitS, lit)==Ordering::LESS;
});
}
}